feat: add isAccountWritable and isAccountSigner to MessageV0 (#27808)

This commit is contained in:
Justin Starry 2022-09-15 14:31:43 -04:00 committed by GitHub
parent b9700244b5
commit 07a83e0fbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 174 additions and 8 deletions

View File

@ -130,14 +130,18 @@ export class Message {
}
isAccountWritable(index: number): boolean {
return (
index <
this.header.numRequiredSignatures -
this.header.numReadonlySignedAccounts ||
(index >= this.header.numRequiredSignatures &&
index <
this.accountKeys.length - this.header.numReadonlyUnsignedAccounts)
);
const numSignedAccounts = this.header.numRequiredSignatures;
if (index >= this.header.numRequiredSignatures) {
const unsignedAccountIndex = index - numSignedAccounts;
const numUnsignedAccounts = this.accountKeys.length - numSignedAccounts;
const numWritableUnsignedAccounts =
numUnsignedAccounts - this.header.numReadonlyUnsignedAccounts;
return unsignedAccountIndex < numWritableUnsignedAccounts;
} else {
const numWritableSignedAccounts =
numSignedAccounts - this.header.numReadonlySignedAccounts;
return index < numWritableSignedAccounts;
}
}
isProgramId(index: number): boolean {

View File

@ -103,6 +103,33 @@ export class MessageV0 {
);
}
isAccountSigner(index: number): boolean {
return index < this.header.numRequiredSignatures;
}
isAccountWritable(index: number): boolean {
const numSignedAccounts = this.header.numRequiredSignatures;
const numStaticAccountKeys = this.staticAccountKeys.length;
if (index >= numStaticAccountKeys) {
const lookupAccountKeysIndex = index - numStaticAccountKeys;
const numWritableLookupAccountKeys = this.addressTableLookups.reduce(
(count, lookup) => count + lookup.writableIndexes.length,
0,
);
return lookupAccountKeysIndex < numWritableLookupAccountKeys;
} else if (index >= this.header.numRequiredSignatures) {
const unsignedAccountIndex = index - numSignedAccounts;
const numUnsignedAccounts = numStaticAccountKeys - numSignedAccounts;
const numWritableUnsignedAccounts =
numUnsignedAccounts - this.header.numReadonlyUnsignedAccounts;
return unsignedAccountIndex < numWritableUnsignedAccounts;
} else {
const numWritableSignedAccounts =
numSignedAccounts - this.header.numReadonlySignedAccounts;
return index < numWritableSignedAccounts;
}
}
resolveAddressTableLookups(
addressLookupTableAccounts: AddressLookupTableAccount[],
): AccountKeysFromLookups {

View File

@ -88,4 +88,56 @@ describe('Message', () => {
expect(message.instructions.length).to.eq(0);
expect(message.recentBlockhash).to.eq(recentBlockhash);
});
it('isAccountWritable', () => {
const accountKeys = [
PublicKey.unique(),
PublicKey.unique(),
PublicKey.unique(),
PublicKey.unique(),
];
const recentBlockhash = bs58.encode(sha256('test'));
const message = new Message({
header: {
numRequiredSignatures: 2,
numReadonlySignedAccounts: 1,
numReadonlyUnsignedAccounts: 1,
},
recentBlockhash,
accountKeys,
instructions: [],
});
expect(message.isAccountWritable(0)).to.be.true;
expect(message.isAccountWritable(1)).to.be.false;
expect(message.isAccountWritable(2)).to.be.true;
expect(message.isAccountWritable(3)).to.be.false;
});
it('isAccountSigner', () => {
const accountKeys = [
PublicKey.unique(),
PublicKey.unique(),
PublicKey.unique(),
PublicKey.unique(),
];
const recentBlockhash = bs58.encode(sha256('test'));
const message = new Message({
header: {
numRequiredSignatures: 2,
numReadonlySignedAccounts: 1,
numReadonlyUnsignedAccounts: 1,
},
recentBlockhash,
accountKeys,
instructions: [],
});
expect(message.isAccountSigner(0)).to.be.true;
expect(message.isAccountSigner(1)).to.be.true;
expect(message.isAccountSigner(2)).to.be.false;
expect(message.isAccountSigner(3)).to.be.false;
});
});

View File

@ -298,4 +298,87 @@ describe('MessageV0', () => {
'Expected versioned message with version 0 but found version 1',
);
});
it('isAccountWritable', () => {
const staticAccountKeys = [
PublicKey.unique(),
PublicKey.unique(),
PublicKey.unique(),
PublicKey.unique(),
];
const recentBlockhash = bs58.encode(sha256('test'));
const message = new MessageV0({
header: {
numRequiredSignatures: 2,
numReadonlySignedAccounts: 1,
numReadonlyUnsignedAccounts: 1,
},
recentBlockhash,
staticAccountKeys,
compiledInstructions: [],
addressTableLookups: [
{
accountKey: PublicKey.unique(),
writableIndexes: [0],
readonlyIndexes: [1],
},
{
accountKey: PublicKey.unique(),
writableIndexes: [0],
readonlyIndexes: [1],
},
],
});
expect(message.isAccountWritable(0)).to.be.true;
expect(message.isAccountWritable(1)).to.be.false;
expect(message.isAccountWritable(2)).to.be.true;
expect(message.isAccountWritable(3)).to.be.false;
expect(message.isAccountWritable(4)).to.be.true;
expect(message.isAccountWritable(5)).to.be.true;
expect(message.isAccountWritable(6)).to.be.false;
expect(message.isAccountWritable(7)).to.be.false;
});
it('isAccountSigner', () => {
const staticAccountKeys = [
PublicKey.unique(),
PublicKey.unique(),
PublicKey.unique(),
PublicKey.unique(),
];
const recentBlockhash = bs58.encode(sha256('test'));
const message = new MessageV0({
header: {
numRequiredSignatures: 2,
numReadonlySignedAccounts: 1,
numReadonlyUnsignedAccounts: 1,
},
recentBlockhash,
staticAccountKeys,
compiledInstructions: [],
addressTableLookups: [
{
accountKey: PublicKey.unique(),
writableIndexes: [0],
readonlyIndexes: [1],
},
{
accountKey: PublicKey.unique(),
writableIndexes: [0],
readonlyIndexes: [1],
},
],
});
expect(message.isAccountSigner(0)).to.be.true;
expect(message.isAccountSigner(1)).to.be.true;
for (let i = 2; i < 8; i++) {
expect(message.isAccountSigner(i)).to.be.false;
}
});
});