Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.

Commit 6b105ee

Browse files
committedJun 4, 2022
fix: repair sort order of pubkeys when compiling messages
1 parent a52f423 commit 6b105ee

File tree

2 files changed

+76
-42
lines changed

2 files changed

+76
-42
lines changed
 

‎src/transaction.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -403,8 +403,8 @@ export class Transaction {
403403
// Writable accounts always come before read-only accounts
404404
return x.isWritable ? -1 : 1;
405405
}
406-
// Otherwise, sort by pubkey.
407-
return x.pubkey._bn.cmp(y.pubkey._bn);
406+
// Otherwise, sort by pubkey, stringwise.
407+
return x.pubkey.toBase58().localeCompare(y.pubkey.toBase58());
408408
});
409409

410410
// Move fee payer to the front

‎test/transaction.test.ts

+74-40
Original file line numberDiff line numberDiff line change
@@ -18,70 +18,104 @@ import {url} from './url';
1818
describe('Transaction', () => {
1919
describe('compileMessage', () => {
2020
it('accountKeys are ordered', () => {
21-
const payer = Keypair.generate();
22-
const accountRegular2 = new PublicKey(2);
23-
const accountRegular3 = new PublicKey(3);
24-
const accountWritable4 = new PublicKey(4);
25-
const accountWritable5 = new PublicKey(5);
26-
const accountSigner6 = new PublicKey(6);
27-
const accountSigner7 = new PublicKey(7);
28-
const accountWritableSigner8 = new PublicKey(8);
29-
const accountWritableSigner9 = new PublicKey(9);
21+
// These pubkeys are chosen specially to be in sort order.
22+
const payer = new PublicKey(
23+
'3qMLYYyNvaxNZP7nW8u5abHMoJthYqQehRLbFVPNNcvQ',
24+
);
25+
const accountWritableSigner2 = new PublicKey(
26+
'3XLtLo5Z4DG8b6PteJidF6kFPNDfxWjxv4vTLrjaHTvd',
27+
);
28+
const accountWritableSigner3 = new PublicKey(
29+
'4rvqGPb4sXgyUKQcvmPxnWEZTTiTqNUZ2jjnw7atKVxa',
30+
);
31+
const accountSigner4 = new PublicKey(
32+
'5oGjWjyoKDoXGpboGBfqm9a5ZscyAjRi3xuGYYu1ayQg',
33+
);
34+
const accountSigner5 = new PublicKey(
35+
'65Rkc3VmDEV6zTRGtgdwkTcQUxDJnJszj2s4WoXazYpC',
36+
);
37+
const accountWritable6 = new PublicKey(
38+
'72BxBZ9eD9Ue6zoJ9bzfit7MuaDAnq1qhirgAoFUXz9q',
39+
);
40+
const accountWritable7 = new PublicKey(
41+
'BtYrPUeVphVgRHJkf2bKz8DLRxJdQmZyANrTM12xFqZL',
42+
);
43+
const accountRegular8 = new PublicKey(
44+
'Di1MbqFwpodKzNrkjGaUHhXC4TJ1SHUAxo9agPZphNH1',
45+
);
46+
const accountRegular9 = new PublicKey(
47+
'DYzzsfHTgaNhCgn7wMaciAYuwYsGqtVNg9PeFZhH93Pc',
48+
);
49+
const programId = new PublicKey(
50+
'Fx9svCTdxnACvmEmx672v2kP1or4G1zC73tH7XsXbKkP',
51+
);
3052

3153
const recentBlockhash = Keypair.generate().publicKey.toBase58();
32-
const programId = Keypair.generate().publicKey;
3354
const transaction = new Transaction({
3455
blockhash: recentBlockhash,
3556
lastValidBlockHeight: 9999,
3657
}).add({
3758
keys: [
3859
// Regular accounts
39-
{pubkey: accountRegular3, isSigner: false, isWritable: false},
40-
{pubkey: accountRegular2, isSigner: false, isWritable: false},
60+
{pubkey: accountRegular9, isSigner: false, isWritable: false},
61+
{pubkey: accountRegular8, isSigner: false, isWritable: false},
4162
// Writable accounts
42-
{pubkey: accountWritable5, isSigner: false, isWritable: true},
43-
{pubkey: accountWritable4, isSigner: false, isWritable: true},
63+
{pubkey: accountWritable7, isSigner: false, isWritable: true},
64+
{pubkey: accountWritable6, isSigner: false, isWritable: true},
4465
// Signers
45-
{pubkey: accountSigner7, isSigner: true, isWritable: false},
46-
{pubkey: accountSigner6, isSigner: true, isWritable: false},
66+
{pubkey: accountSigner5, isSigner: true, isWritable: false},
67+
{pubkey: accountSigner4, isSigner: true, isWritable: false},
4768
// Writable Signers
48-
{pubkey: accountWritableSigner9, isSigner: true, isWritable: true},
49-
{pubkey: accountWritableSigner8, isSigner: true, isWritable: true},
69+
{pubkey: accountWritableSigner3, isSigner: true, isWritable: true},
70+
{pubkey: accountWritableSigner2, isSigner: true, isWritable: true},
5071
// Payer.
51-
{pubkey: payer.publicKey, isSigner: true, isWritable: true},
72+
{pubkey: payer, isSigner: true, isWritable: true},
5273
],
5374
programId,
5475
});
5576

56-
transaction.feePayer = payer.publicKey;
77+
transaction.feePayer = payer;
5778

5879
const message = transaction.compileMessage();
5980
// Payer comes first.
60-
expect(message.accountKeys[0].equals(payer.publicKey)).to.be.true;
81+
expect(message.accountKeys[0].equals(payer)).to.be.true;
6182
// Writable signers come next, in pubkey order.
62-
expect(message.accountKeys[1].equals(accountWritableSigner8)).to.be.true;
63-
expect(message.accountKeys[2].equals(accountWritableSigner9)).to.be.true;
83+
expect(message.accountKeys[1].equals(accountWritableSigner2)).to.be.true;
84+
expect(message.accountKeys[2].equals(accountWritableSigner3)).to.be.true;
6485
// Signers come next, in pubkey order.
65-
expect(message.accountKeys[3].equals(accountSigner6)).to.be.true;
66-
expect(message.accountKeys[4].equals(accountSigner7)).to.be.true;
86+
expect(message.accountKeys[3].equals(accountSigner4)).to.be.true;
87+
expect(message.accountKeys[4].equals(accountSigner5)).to.be.true;
6788
// Writable accounts come next, in pubkey order.
68-
expect(message.accountKeys[5].equals(accountWritable4)).to.be.true;
69-
expect(message.accountKeys[6].equals(accountWritable5)).to.be.true;
89+
expect(message.accountKeys[5].equals(accountWritable6)).to.be.true;
90+
expect(message.accountKeys[6].equals(accountWritable7)).to.be.true;
7091
// Everything else afterward, in pubkey order.
71-
expect(message.accountKeys[7].equals(accountRegular2)).to.be.true;
72-
expect(message.accountKeys[8].equals(accountRegular3)).to.be.true;
92+
expect(message.accountKeys[7].equals(accountRegular8)).to.be.true;
93+
expect(message.accountKeys[8].equals(accountRegular9)).to.be.true;
7394
expect(message.accountKeys[9].equals(programId)).to.be.true;
7495
});
7596

7697
it('accountKeys collapses signedness and writability of duplicate accounts', () => {
77-
const payer = Keypair.generate();
78-
const account2 = new PublicKey(2);
79-
const account3 = new PublicKey(3);
80-
const account4 = new PublicKey(4);
81-
const account5 = new PublicKey(5);
98+
// These pubkeys are chosen specially to be in sort order.
99+
const payer = new PublicKey(
100+
'2eBgaMN8dCnCjx8B8Wrwk974v5WHwA6Vvj4N2mW9KDyt',
101+
);
102+
const account2 = new PublicKey(
103+
'DL8FErokCN7rerLdmJ7tQvsL1FsqDu1sTKLLooWmChiW',
104+
);
105+
const account3 = new PublicKey(
106+
'EdPiTYbXFxNrn1vqD7ZdDyauRKG4hMR6wY54RU1YFP2e',
107+
);
108+
const account4 = new PublicKey(
109+
'FThXbyKK4kYJBngSSuvo9e6kc7mwPHEgw4V8qdmz1h3k',
110+
);
111+
const programId = new PublicKey(
112+
'Gcatgv533efD1z2knsH9UKtkrjRWCZGi12f8MjNaDzmN',
113+
);
114+
const account5 = new PublicKey(
115+
'rBtwG4bx85Exjr9cgoupvP1c7VTe7u5B36rzCg1HYgi',
116+
);
82117

83118
const recentBlockhash = Keypair.generate().publicKey.toBase58();
84-
const programId = Keypair.generate().publicKey;
85119
const transaction = new Transaction({
86120
blockhash: recentBlockhash,
87121
lastValidBlockHeight: 9999,
@@ -100,25 +134,25 @@ describe('Transaction', () => {
100134
{pubkey: account2, isSigner: false, isWritable: true},
101135
{pubkey: account2, isSigner: true, isWritable: false},
102136
// Payer.
103-
{pubkey: payer.publicKey, isSigner: true, isWritable: true},
137+
{pubkey: payer, isSigner: true, isWritable: true},
104138
],
105139
programId,
106140
});
107141

108-
transaction.feePayer = payer.publicKey;
142+
transaction.feePayer = payer;
109143

110144
const message = transaction.compileMessage();
111145
// Payer comes first.
112-
expect(message.accountKeys[0].equals(payer.publicKey)).to.be.true;
146+
expect(message.accountKeys[0].equals(payer)).to.be.true;
113147
// Writable signer comes first.
114148
expect(message.accountKeys[1].equals(account2)).to.be.true;
115149
// Signer comes next.
116150
expect(message.accountKeys[2].equals(account3)).to.be.true;
117151
// Writable account comes next.
118152
expect(message.accountKeys[3].equals(account4)).to.be.true;
119153
// Regular accounts come last.
120-
expect(message.accountKeys[4].equals(account5)).to.be.true;
121-
expect(message.accountKeys[5].equals(programId)).to.be.true;
154+
expect(message.accountKeys[4].equals(programId)).to.be.true;
155+
expect(message.accountKeys[5].equals(account5)).to.be.true;
122156
});
123157

124158
it('payer is first account meta', () => {

0 commit comments

Comments
 (0)
This repository has been archived.