fix: sort accountMetas after deduping
This commit is contained in:
parent
4b1dd0f921
commit
20f169c0b0
|
@ -376,17 +376,6 @@ export class Transaction {
|
|||
});
|
||||
});
|
||||
|
||||
// Sort. Prioritizing first by signer, then by writable
|
||||
accountMetas.sort(function (x, y) {
|
||||
const pubkeySorting = x.pubkey
|
||||
.toBase58()
|
||||
.localeCompare(y.pubkey.toBase58());
|
||||
const checkSigner = x.isSigner === y.isSigner ? 0 : x.isSigner ? -1 : 1;
|
||||
const checkWritable =
|
||||
x.isWritable === y.isWritable ? pubkeySorting : x.isWritable ? -1 : 1;
|
||||
return checkSigner || checkWritable;
|
||||
});
|
||||
|
||||
// Cull duplicate account metas
|
||||
const uniqueMetas: AccountMeta[] = [];
|
||||
accountMetas.forEach(accountMeta => {
|
||||
|
@ -397,11 +386,24 @@ export class Transaction {
|
|||
if (uniqueIndex > -1) {
|
||||
uniqueMetas[uniqueIndex].isWritable =
|
||||
uniqueMetas[uniqueIndex].isWritable || accountMeta.isWritable;
|
||||
uniqueMetas[uniqueIndex].isSigner =
|
||||
uniqueMetas[uniqueIndex].isSigner || accountMeta.isSigner;
|
||||
} else {
|
||||
uniqueMetas.push(accountMeta);
|
||||
}
|
||||
});
|
||||
|
||||
// Sort. Prioritizing first by signer, then by writable
|
||||
uniqueMetas.sort(function (x, y) {
|
||||
const pubkeySorting = x.pubkey
|
||||
.toBase58()
|
||||
.localeCompare(y.pubkey.toBase58());
|
||||
const checkSigner = x.isSigner === y.isSigner ? 0 : x.isSigner ? -1 : 1;
|
||||
const checkWritable =
|
||||
x.isWritable === y.isWritable ? pubkeySorting : x.isWritable ? -1 : 1;
|
||||
return checkSigner || checkWritable;
|
||||
});
|
||||
|
||||
// Move fee payer to the front
|
||||
const feePayerIndex = uniqueMetas.findIndex(x => {
|
||||
return x.pubkey.equals(feePayer);
|
||||
|
|
|
@ -47,6 +47,33 @@ describe('Transaction', () => {
|
|||
expect(message.accountKeys[2]).to.eql(account3.publicKey);
|
||||
});
|
||||
|
||||
it('accountKeys are sorted & deduplicated correctly', () => {
|
||||
const payer = Keypair.generate();
|
||||
const account2 = new PublicKey(2);
|
||||
const account3 = new PublicKey(1);
|
||||
const recentBlockhash = Keypair.generate().publicKey.toBase58();
|
||||
const programId = Keypair.generate().publicKey;
|
||||
const transaction = new Transaction({
|
||||
blockhash: recentBlockhash,
|
||||
lastValidBlockHeight: 9999,
|
||||
}).add({
|
||||
keys: [
|
||||
{pubkey: account3, isSigner: true, isWritable: false},
|
||||
{pubkey: payer.publicKey, isSigner: true, isWritable: true},
|
||||
{pubkey: account2, isSigner: false, isWritable: true},
|
||||
{pubkey: account2, isSigner: true, isWritable: false},
|
||||
],
|
||||
programId,
|
||||
});
|
||||
|
||||
transaction.feePayer = payer.publicKey;
|
||||
|
||||
const message = transaction.compileMessage();
|
||||
expect(message.accountKeys[0]).to.eql(payer.publicKey);
|
||||
expect(message.accountKeys[1].toBase58()).to.eql(account2.toBase58());
|
||||
expect(message.accountKeys[2].toBase58()).to.eql(account3.toBase58());
|
||||
});
|
||||
|
||||
it('payer is first account meta', () => {
|
||||
const payer = Keypair.generate();
|
||||
const other = Keypair.generate();
|
||||
|
|
Loading…
Reference in New Issue