feat: allow setting explicit fee payer for transaction (#13129)
This commit is contained in:
@ -176,7 +176,7 @@ describe('load BPF Rust program', () => {
|
||||
);
|
||||
});
|
||||
|
||||
test('simulate transaction without signature verification', async () => {
|
||||
test('deprecated - simulate transaction without signature verification', async () => {
|
||||
const simulatedTransaction = new Transaction().add({
|
||||
keys: [
|
||||
{pubkey: payerAccount.publicKey, isSigner: true, isWritable: true},
|
||||
@ -202,6 +202,33 @@ describe('load BPF Rust program', () => {
|
||||
);
|
||||
});
|
||||
|
||||
test('simulate transaction without signature verification', async () => {
|
||||
const simulatedTransaction = new Transaction({
|
||||
feePayer: payerAccount.publicKey,
|
||||
}).add({
|
||||
keys: [
|
||||
{pubkey: payerAccount.publicKey, isSigner: true, isWritable: true},
|
||||
],
|
||||
programId: program.publicKey,
|
||||
});
|
||||
|
||||
const {err, logs} = (
|
||||
await connection.simulateTransaction(simulatedTransaction)
|
||||
).value;
|
||||
expect(err).toBeNull();
|
||||
|
||||
if (logs === null) {
|
||||
expect(logs).not.toBeNull();
|
||||
return;
|
||||
}
|
||||
|
||||
expect(logs.length).toBeGreaterThanOrEqual(2);
|
||||
expect(logs[0]).toEqual(`Call BPF program ${program.publicKey.toBase58()}`);
|
||||
expect(logs[logs.length - 1]).toEqual(
|
||||
`BPF program ${program.publicKey.toBase58()} success`,
|
||||
);
|
||||
});
|
||||
|
||||
test('simulate transaction with bad programId', async () => {
|
||||
const simulatedTransaction = new Transaction().add({
|
||||
keys: [
|
||||
|
@ -198,8 +198,8 @@ test('get program accounts', async () => {
|
||||
},
|
||||
]);
|
||||
|
||||
if (transaction.recentBlockhash === null) {
|
||||
expect(transaction.recentBlockhash).not.toBeNull();
|
||||
if (!transaction.recentBlockhash) {
|
||||
expect(transaction.recentBlockhash).toBeTruthy();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -86,19 +86,22 @@ describe('compileMessage', () => {
|
||||
|
||||
expect(() => {
|
||||
transaction.compileMessage();
|
||||
}).toThrow('Transaction feePayer required');
|
||||
|
||||
transaction.setSigners(payer.publicKey);
|
||||
|
||||
expect(() => {
|
||||
transaction.compileMessage();
|
||||
}).toThrow('missing signer');
|
||||
}).toThrow('Transaction fee payer required');
|
||||
|
||||
transaction.setSigners(payer.publicKey, new Account().publicKey);
|
||||
|
||||
expect(() => {
|
||||
transaction.compileMessage();
|
||||
}).toThrow('unknown signer');
|
||||
|
||||
// Expect compile to succeed with implicit fee payer from signers
|
||||
transaction.setSigners(payer.publicKey);
|
||||
transaction.compileMessage();
|
||||
|
||||
// Expect compile to succeed with fee payer and no signers
|
||||
transaction.signatures = [];
|
||||
transaction.feePayer = payer.publicKey;
|
||||
transaction.compileMessage();
|
||||
});
|
||||
|
||||
test('payer is writable', () => {
|
||||
@ -260,6 +263,7 @@ test('transfer signatures', () => {
|
||||
|
||||
const newTransaction = new Transaction({
|
||||
recentBlockhash: orgTransaction.recentBlockhash,
|
||||
feePayer: orgTransaction.feePayer,
|
||||
signatures: orgTransaction.signatures,
|
||||
}).add(transfer1, transfer2);
|
||||
|
||||
@ -354,7 +358,10 @@ test('parse wire format and serialize', () => {
|
||||
toPubkey: recipient,
|
||||
lamports: 49,
|
||||
});
|
||||
const expectedTransaction = new Transaction({recentBlockhash}).add(transfer);
|
||||
const expectedTransaction = new Transaction({
|
||||
recentBlockhash,
|
||||
feePayer: sender.publicKey,
|
||||
}).add(transfer);
|
||||
expectedTransaction.sign(sender);
|
||||
|
||||
const wireTransaction = Buffer.from(
|
||||
@ -423,21 +430,38 @@ test('serialize unsigned transaction', () => {
|
||||
expect(expectedTransaction.signatures.length).toBe(0);
|
||||
expect(() => {
|
||||
expectedTransaction.serialize();
|
||||
}).toThrow(Error);
|
||||
}).toThrow('Transaction fee payer required');
|
||||
expect(() => {
|
||||
expectedTransaction.serialize({verifySignatures: false});
|
||||
}).toThrow(Error);
|
||||
}).toThrow('Transaction fee payer required');
|
||||
expect(() => {
|
||||
expectedTransaction.serializeMessage();
|
||||
}).toThrow('Transaction feePayer required');
|
||||
}).toThrow('Transaction fee payer required');
|
||||
|
||||
expectedTransaction.feePayer = sender.publicKey;
|
||||
|
||||
// Transactions with missing signatures will fail sigverify.
|
||||
expect(() => {
|
||||
expectedTransaction.serialize();
|
||||
}).toThrow('Signature verification failed');
|
||||
|
||||
// Serializing without signatures is allowed if sigverify disabled.
|
||||
expectedTransaction.serialize({verifySignatures: false});
|
||||
|
||||
// Serializing the message is allowed when signature array has null signatures
|
||||
expectedTransaction.serializeMessage();
|
||||
|
||||
expectedTransaction.feePayer = null;
|
||||
expectedTransaction.setSigners(sender.publicKey);
|
||||
expect(expectedTransaction.signatures.length).toBe(1);
|
||||
|
||||
// Signature array populated with null signatures fails.
|
||||
// Transactions with missing signatures will fail sigverify.
|
||||
expect(() => {
|
||||
expectedTransaction.serialize();
|
||||
}).toThrow(Error);
|
||||
}).toThrow('Signature verification failed');
|
||||
|
||||
// Serializing without signatures is allowed if sigverify disabled.
|
||||
expectedTransaction.serialize({verifySignatures: false});
|
||||
|
||||
// Serializing the message is allowed when signature array has null signatures
|
||||
expectedTransaction.serializeMessage();
|
||||
@ -468,7 +492,7 @@ test('serialize unsigned transaction', () => {
|
||||
expect(expectedTransaction.signatures.length).toBe(1);
|
||||
});
|
||||
|
||||
test('externally signed stake delegate', () => {
|
||||
test('deprecated - externally signed stake delegate', () => {
|
||||
const from_keypair = nacl.sign.keyPair.fromSeed(
|
||||
Uint8Array.from(Array(32).fill(1)),
|
||||
);
|
||||
@ -489,3 +513,25 @@ test('externally signed stake delegate', () => {
|
||||
tx.addSignature(from.publicKey, signature);
|
||||
expect(tx.verifySignatures()).toBe(true);
|
||||
});
|
||||
|
||||
test('externally signed stake delegate', () => {
|
||||
const from_keypair = nacl.sign.keyPair.fromSeed(
|
||||
Uint8Array.from(Array(32).fill(1)),
|
||||
);
|
||||
const authority = new Account(Buffer.from(from_keypair.secretKey));
|
||||
const stake = new PublicKey(2);
|
||||
const recentBlockhash = new PublicKey(3).toBuffer();
|
||||
const vote = new PublicKey(4);
|
||||
var tx = StakeProgram.delegate({
|
||||
stakePubkey: stake,
|
||||
authorizedPubkey: authority.publicKey,
|
||||
votePubkey: vote,
|
||||
});
|
||||
const from = authority;
|
||||
tx.recentBlockhash = bs58.encode(recentBlockhash);
|
||||
tx.feePayer = from.publicKey;
|
||||
const tx_bytes = tx.serializeMessage();
|
||||
const signature = nacl.sign.detached(tx_bytes, from.secretKey);
|
||||
tx.addSignature(from.publicKey, signature);
|
||||
expect(tx.verifySignatures()).toBe(true);
|
||||
});
|
||||
|
Reference in New Issue
Block a user