fix: inconsistent tx message compilation accounting
This commit is contained in:
committed by
Trent Nelson
parent
40800e257c
commit
a8b1d71ae6
@ -210,9 +210,6 @@ export class Transaction {
|
|||||||
let numReadonlySignedAccounts = 0;
|
let numReadonlySignedAccounts = 0;
|
||||||
let numReadonlyUnsignedAccounts = 0;
|
let numReadonlyUnsignedAccounts = 0;
|
||||||
|
|
||||||
const accountKeys = this.signatures.map(({publicKey}) =>
|
|
||||||
publicKey.toString(),
|
|
||||||
);
|
|
||||||
const programIds: string[] = [];
|
const programIds: string[] = [];
|
||||||
const accountMetas: AccountMeta[] = [];
|
const accountMetas: AccountMeta[] = [];
|
||||||
this.instructions.forEach(instruction => {
|
this.instructions.forEach(instruction => {
|
||||||
@ -226,6 +223,18 @@ export class Transaction {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Append programID account metas
|
||||||
|
programIds.forEach(programId => {
|
||||||
|
accountMetas.push({
|
||||||
|
pubkey: new PublicKey(programId),
|
||||||
|
isSigner: false,
|
||||||
|
isWritable: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Prefix accountMetas with feePayer here whenever that gets implemented
|
||||||
|
|
||||||
|
// Sort. Prioritizing first by signer, then by writable
|
||||||
accountMetas.sort(function (x, y) {
|
accountMetas.sort(function (x, y) {
|
||||||
const checkSigner = x.isSigner === y.isSigner ? 0 : x.isSigner ? -1 : 1;
|
const checkSigner = x.isSigner === y.isSigner ? 0 : x.isSigner ? -1 : 1;
|
||||||
const checkWritable =
|
const checkWritable =
|
||||||
@ -233,31 +242,66 @@ export class Transaction {
|
|||||||
return checkSigner || checkWritable;
|
return checkSigner || checkWritable;
|
||||||
});
|
});
|
||||||
|
|
||||||
accountMetas.forEach(({pubkey, isSigner, isWritable}) => {
|
// Cull duplicate account metas
|
||||||
const keyStr = pubkey.toString();
|
const uniqueMetas: AccountMeta[] = [];
|
||||||
if (!accountKeys.includes(keyStr)) {
|
accountMetas.forEach(accountMeta => {
|
||||||
accountKeys.push(keyStr);
|
const pubkeyString = accountMeta.pubkey.toString();
|
||||||
if (isSigner) {
|
const uniqueIndex = uniqueMetas.findIndex(x => {
|
||||||
this.signatures.push({
|
return x.pubkey.toString() === pubkeyString;
|
||||||
signature: null,
|
});
|
||||||
publicKey: pubkey,
|
if (uniqueIndex > -1) {
|
||||||
});
|
uniqueMetas[uniqueIndex].isWritable =
|
||||||
if (!isWritable) {
|
uniqueMetas[uniqueIndex].isWritable || accountMeta.isWritable;
|
||||||
numReadonlySignedAccounts += 1;
|
} else {
|
||||||
}
|
uniqueMetas.push(accountMeta);
|
||||||
} else if (!isWritable) {
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.signatures.forEach(signature => {
|
||||||
|
const sigPubkeyString = signature.publicKey.toString();
|
||||||
|
const uniqueIndex = uniqueMetas.findIndex(x => {
|
||||||
|
return x.pubkey.toString() === sigPubkeyString;
|
||||||
|
});
|
||||||
|
if (uniqueIndex > -1) {
|
||||||
|
uniqueMetas[uniqueIndex].isSigner = true;
|
||||||
|
} else {
|
||||||
|
uniqueMetas.unshift({
|
||||||
|
pubkey: new PublicKey(sigPubkeyString),
|
||||||
|
isSigner: true,
|
||||||
|
isWritable: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Split out signing from nonsigning keys and count readonlys
|
||||||
|
const signedKeys: string[] = [];
|
||||||
|
const unsignedKeys: string[] = [];
|
||||||
|
uniqueMetas.forEach(({pubkey, isSigner, isWritable}) => {
|
||||||
|
if (isSigner) {
|
||||||
|
// Promote the first signer to writable as it is the fee payer
|
||||||
|
const first = signedKeys.length === 0;
|
||||||
|
signedKeys.push(pubkey.toString());
|
||||||
|
if (!first && !isWritable) {
|
||||||
|
numReadonlySignedAccounts += 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unsignedKeys.push(pubkey.toString());
|
||||||
|
if (!isWritable) {
|
||||||
numReadonlyUnsignedAccounts += 1;
|
numReadonlyUnsignedAccounts += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
programIds.forEach(programId => {
|
// Initialize signature array, if needed
|
||||||
if (!accountKeys.includes(programId)) {
|
if (this.signatures.length === 0) {
|
||||||
accountKeys.push(programId);
|
const signatures: Array<SignaturePubkeyPair> = [];
|
||||||
numReadonlyUnsignedAccounts += 1;
|
signedKeys.forEach(pubkey => {
|
||||||
}
|
signatures.push({signature: null, publicKey: new PublicKey(pubkey)});
|
||||||
});
|
});
|
||||||
|
this.signatures = signatures;
|
||||||
|
}
|
||||||
|
|
||||||
|
const accountKeys = signedKeys.concat(unsignedKeys);
|
||||||
const instructions: CompiledInstruction[] = this.instructions.map(
|
const instructions: CompiledInstruction[] = this.instructions.map(
|
||||||
instruction => {
|
instruction => {
|
||||||
const {data, programId} = instruction;
|
const {data, programId} = instruction;
|
||||||
|
Reference in New Issue
Block a user