fix: Add preliminary handling for credit-only account designation
This commit is contained in:
committed by
Michael Vines
parent
78ad376bcd
commit
c99d8dd15c
@ -124,13 +124,13 @@ declare module '@solana/web3.js' {
|
||||
declare export type TransactionSignature = string;
|
||||
|
||||
declare type TransactionInstructionCtorFields = {|
|
||||
keys: ?Array<{pubkey: PublicKey, isSigner: boolean}>,
|
||||
keys: ?Array<{pubkey: PublicKey, isSigner: boolean, isDebitable: boolean}>,
|
||||
programId?: PublicKey,
|
||||
data?: Buffer,
|
||||
|};
|
||||
|
||||
declare export class TransactionInstruction {
|
||||
keys: Array<{pubkey: PublicKey, isSigner: boolean}>;
|
||||
keys: Array<{pubkey: PublicKey, isSigner: boolean, isDebitable: boolean}>;
|
||||
programId: PublicKey;
|
||||
data: Buffer;
|
||||
}
|
||||
|
@ -201,7 +201,10 @@ export class BudgetProgram {
|
||||
}
|
||||
|
||||
return new Transaction().add({
|
||||
keys: [{pubkey: from, isSigner: true}, {pubkey: to, isSigner: false}],
|
||||
keys: [
|
||||
{pubkey: from, isSigner: true, isDebitable: true},
|
||||
{pubkey: to, isSigner: false, isDebitable: false},
|
||||
],
|
||||
programId: this.programId,
|
||||
data: data.slice(0, pos),
|
||||
});
|
||||
@ -222,9 +225,9 @@ export class BudgetProgram {
|
||||
|
||||
return new Transaction().add({
|
||||
keys: [
|
||||
{pubkey: from, isSigner: true},
|
||||
{pubkey: program, isSigner: false},
|
||||
{pubkey: to, isSigner: false},
|
||||
{pubkey: from, isSigner: true, isDebitable: true},
|
||||
{pubkey: program, isSigner: false, isDebitable: true},
|
||||
{pubkey: to, isSigner: false, isDebitable: false},
|
||||
],
|
||||
programId: this.programId,
|
||||
data: data.slice(0, pos),
|
||||
@ -246,9 +249,9 @@ export class BudgetProgram {
|
||||
|
||||
return new Transaction().add({
|
||||
keys: [
|
||||
{pubkey: from, isSigner: true},
|
||||
{pubkey: program, isSigner: false},
|
||||
{pubkey: to, isSigner: false},
|
||||
{pubkey: from, isSigner: true, isDebitable: true},
|
||||
{pubkey: program, isSigner: false, isDebitable: true},
|
||||
{pubkey: to, isSigner: false, isDebitable: false},
|
||||
],
|
||||
programId: this.programId,
|
||||
data: data.slice(0, pos),
|
||||
@ -294,9 +297,9 @@ export class BudgetProgram {
|
||||
|
||||
return new Transaction().add({
|
||||
keys: [
|
||||
{pubkey: from, isSigner: true},
|
||||
{pubkey: program, isSigner: false},
|
||||
{pubkey: to, isSigner: false},
|
||||
{pubkey: from, isSigner: true, isDebitable: true},
|
||||
{pubkey: program, isSigner: false, isDebitable: true},
|
||||
{pubkey: to, isSigner: false, isDebitable: false},
|
||||
],
|
||||
programId: this.programId,
|
||||
data: data.slice(0, pos),
|
||||
@ -321,9 +324,9 @@ export class BudgetProgram {
|
||||
|
||||
return new Transaction().add({
|
||||
keys: [
|
||||
{pubkey: from, isSigner: true},
|
||||
{pubkey: program, isSigner: false},
|
||||
{pubkey: to, isSigner: false},
|
||||
{pubkey: from, isSigner: true, isDebitable: true},
|
||||
{pubkey: program, isSigner: false, isDebitable: true},
|
||||
{pubkey: to, isSigner: false, isDebitable: false},
|
||||
],
|
||||
programId: this.programId,
|
||||
data,
|
||||
@ -351,9 +354,9 @@ export class BudgetProgram {
|
||||
|
||||
return new Transaction().add({
|
||||
keys: [
|
||||
{pubkey: from, isSigner: true},
|
||||
{pubkey: program, isSigner: false},
|
||||
{pubkey: to, isSigner: false},
|
||||
{pubkey: from, isSigner: true, isDebitable: true},
|
||||
{pubkey: program, isSigner: false, isDebitable: true},
|
||||
{pubkey: to, isSigner: false, isDebitable: false},
|
||||
],
|
||||
programId: this.programId,
|
||||
data,
|
||||
|
@ -78,7 +78,7 @@ export class Loader {
|
||||
);
|
||||
|
||||
const transaction = new Transaction().add({
|
||||
keys: [{pubkey: program.publicKey, isSigner: true}],
|
||||
keys: [{pubkey: program.publicKey, isSigner: true, isDebitable: true}],
|
||||
programId,
|
||||
data,
|
||||
});
|
||||
@ -117,7 +117,7 @@ export class Loader {
|
||||
);
|
||||
|
||||
const transaction = new Transaction().add({
|
||||
keys: [{pubkey: program.publicKey, isSigner: true}],
|
||||
keys: [{pubkey: program.publicKey, isSigner: true, isDebitable: true}],
|
||||
programId,
|
||||
data,
|
||||
});
|
||||
|
@ -49,8 +49,8 @@ export class SystemProgram {
|
||||
|
||||
return new Transaction().add({
|
||||
keys: [
|
||||
{pubkey: from, isSigner: true},
|
||||
{pubkey: newAccount, isSigner: false},
|
||||
{pubkey: from, isSigner: true, isDebitable: true},
|
||||
{pubkey: newAccount, isSigner: false, isDebitable: true},
|
||||
],
|
||||
programId: SystemProgram.programId,
|
||||
data,
|
||||
@ -76,7 +76,10 @@ export class SystemProgram {
|
||||
);
|
||||
|
||||
return new Transaction().add({
|
||||
keys: [{pubkey: from, isSigner: true}, {pubkey: to, isSigner: false}],
|
||||
keys: [
|
||||
{pubkey: from, isSigner: true, isDebitable: true},
|
||||
{pubkey: to, isSigner: false, isDebitable: false},
|
||||
],
|
||||
programId: SystemProgram.programId,
|
||||
data,
|
||||
});
|
||||
@ -101,7 +104,7 @@ export class SystemProgram {
|
||||
);
|
||||
|
||||
return new Transaction().add({
|
||||
keys: [{pubkey: from, isSigner: true}],
|
||||
keys: [{pubkey: from, isSigner: true, isDebitable: true}],
|
||||
programId: SystemProgram.programId,
|
||||
data,
|
||||
});
|
||||
|
@ -237,8 +237,8 @@ export class Token {
|
||||
|
||||
transaction = new Transaction().add({
|
||||
keys: [
|
||||
{pubkey: tokenAccount.publicKey, isSigner: true},
|
||||
{pubkey: initialAccountPublicKey, isSigner: false},
|
||||
{pubkey: tokenAccount.publicKey, isSigner: true, isDebitable: false},
|
||||
{pubkey: initialAccountPublicKey, isSigner: false, isDebitable: true},
|
||||
],
|
||||
programId,
|
||||
data,
|
||||
@ -292,12 +292,12 @@ export class Token {
|
||||
|
||||
// Initialize the token account
|
||||
const keys = [
|
||||
{pubkey: tokenAccount.publicKey, isSigner: true},
|
||||
{pubkey: owner.publicKey, isSigner: false},
|
||||
{pubkey: this.token, isSigner: false},
|
||||
{pubkey: tokenAccount.publicKey, isSigner: true, isDebitable: true},
|
||||
{pubkey: owner.publicKey, isSigner: false, isDebitable: false},
|
||||
{pubkey: this.token, isSigner: false, isDebitable: false},
|
||||
];
|
||||
if (source) {
|
||||
keys.push({pubkey: source, isSigner: false});
|
||||
keys.push({pubkey: source, isSigner: false, isDebitable: false});
|
||||
}
|
||||
transaction = new Transaction().add({
|
||||
keys,
|
||||
@ -496,12 +496,16 @@ export class Token {
|
||||
);
|
||||
|
||||
const keys = [
|
||||
{pubkey: owner, isSigner: true},
|
||||
{pubkey: source, isSigner: false},
|
||||
{pubkey: destination, isSigner: false},
|
||||
{pubkey: owner, isSigner: true, isDebitable: false},
|
||||
{pubkey: source, isSigner: false, isDebitable: true},
|
||||
{pubkey: destination, isSigner: false, isDebitable: true},
|
||||
];
|
||||
if (accountInfo.source) {
|
||||
keys.push({pubkey: accountInfo.source, isSigner: false});
|
||||
keys.push({
|
||||
pubkey: accountInfo.source,
|
||||
isSigner: false,
|
||||
isDebitable: true,
|
||||
});
|
||||
}
|
||||
return new TransactionInstruction({
|
||||
keys,
|
||||
@ -540,9 +544,9 @@ export class Token {
|
||||
|
||||
return new TransactionInstruction({
|
||||
keys: [
|
||||
{pubkey: owner, isSigner: true},
|
||||
{pubkey: account, isSigner: false},
|
||||
{pubkey: delegate, isSigner: false},
|
||||
{pubkey: owner, isSigner: true, isDebitable: false},
|
||||
{pubkey: account, isSigner: false, isDebitable: true},
|
||||
{pubkey: delegate, isSigner: false, isDebitable: true},
|
||||
],
|
||||
programId: this.programId,
|
||||
data,
|
||||
@ -588,9 +592,9 @@ export class Token {
|
||||
|
||||
return new TransactionInstruction({
|
||||
keys: [
|
||||
{pubkey: owner, isSigner: true},
|
||||
{pubkey: account, isSigner: false},
|
||||
{pubkey: newOwner, isSigner: false},
|
||||
{pubkey: owner, isSigner: true, isDebitable: false},
|
||||
{pubkey: account, isSigner: false, isDebitable: true},
|
||||
{pubkey: newOwner, isSigner: false, isDebitable: true},
|
||||
],
|
||||
programId: this.programId,
|
||||
data,
|
||||
|
@ -30,7 +30,7 @@ export const PACKET_DATA_SIZE = 512;
|
||||
* @property {?Buffer} data
|
||||
*/
|
||||
type TransactionInstructionCtorFields = {|
|
||||
keys?: Array<{pubkey: PublicKey, isSigner: boolean}>,
|
||||
keys?: Array<{pubkey: PublicKey, isSigner: boolean, isDebitable: boolean}>,
|
||||
programId?: PublicKey,
|
||||
data?: Buffer,
|
||||
|};
|
||||
@ -43,7 +43,11 @@ export class TransactionInstruction {
|
||||
* Public keys to include in this transaction
|
||||
* Boolean represents whether this pubkey needs to sign the transaction
|
||||
*/
|
||||
keys: Array<{pubkey: PublicKey, isSigner: boolean}> = [];
|
||||
keys: Array<{
|
||||
pubkey: PublicKey,
|
||||
isSigner: boolean,
|
||||
isDebitable: boolean,
|
||||
}> = [];
|
||||
|
||||
/**
|
||||
* Program Id to execute
|
||||
@ -166,6 +170,13 @@ export class Transaction {
|
||||
if (!keys.includes(keyStr)) {
|
||||
if (keySignerPair.isSigner) {
|
||||
numRequiredSignatures += 1;
|
||||
if (!keySignerPair.isDebitable) {
|
||||
numCreditOnlySignedAccounts += 1;
|
||||
}
|
||||
} else {
|
||||
if (!keySignerPair.isDebitable) {
|
||||
numCreditOnlyUnsignedAccounts += 1;
|
||||
}
|
||||
}
|
||||
keys.push(keyStr);
|
||||
}
|
||||
@ -422,6 +433,20 @@ export class Transaction {
|
||||
const PUBKEY_LENGTH = 32;
|
||||
const SIGNATURE_LENGTH = 64;
|
||||
|
||||
function isCreditDebit(
|
||||
i: number,
|
||||
numRequiredSignatures: number,
|
||||
numCreditOnlySignedAccounts: number,
|
||||
numCreditOnlyUnsignedAccounts: number,
|
||||
numKeys: number,
|
||||
): boolean {
|
||||
return (
|
||||
i < numRequiredSignatures - numCreditOnlySignedAccounts ||
|
||||
(i >= numRequiredSignatures &&
|
||||
i < numKeys - numCreditOnlyUnsignedAccounts)
|
||||
);
|
||||
}
|
||||
|
||||
let transaction = new Transaction();
|
||||
|
||||
// Slice up wire data
|
||||
@ -435,9 +460,12 @@ export class Transaction {
|
||||
signatures.push(signature);
|
||||
}
|
||||
|
||||
byteArray = byteArray.slice(1); // Skip numRequiredSignatures byte
|
||||
byteArray = byteArray.slice(1); // Skip numCreditOnlySignedAccounts byte
|
||||
byteArray = byteArray.slice(1); // Skip numCreditOnlyUnsignedAccounts byte
|
||||
const numRequiredSignatures = byteArray.shift();
|
||||
// byteArray = byteArray.slice(1); // Skip numRequiredSignatures byte
|
||||
const numCreditOnlySignedAccounts = byteArray.shift();
|
||||
// byteArray = byteArray.slice(1); // Skip numCreditOnlySignedAccounts byte
|
||||
const numCreditOnlyUnsignedAccounts = byteArray.shift();
|
||||
// byteArray = byteArray.slice(1); // Skip numCreditOnlyUnsignedAccounts byte
|
||||
|
||||
const accountCount = shortvec.decodeLength(byteArray);
|
||||
let accounts = [];
|
||||
@ -481,11 +509,19 @@ export class Transaction {
|
||||
};
|
||||
for (let j = 0; j < instructions[i].accountIndex.length; j++) {
|
||||
const pubkey = new PublicKey(accounts[instructions[i].accountIndex[j]]);
|
||||
|
||||
instructionData.keys.push({
|
||||
pubkey,
|
||||
isSigner: transaction.signatures.some(
|
||||
keyObj => keyObj.publicKey.toString() === pubkey.toString(),
|
||||
),
|
||||
isDebitable: isCreditDebit(
|
||||
j,
|
||||
numRequiredSignatures,
|
||||
numCreditOnlySignedAccounts,
|
||||
numCreditOnlyUnsignedAccounts,
|
||||
accounts.length,
|
||||
),
|
||||
});
|
||||
}
|
||||
let instruction = new TransactionInstruction(instructionData);
|
||||
|
@ -28,7 +28,7 @@ test('load BPF C program', async () => {
|
||||
const data = await fs.readFile('test/fixtures/noop-c/noop.so');
|
||||
const programId = await BpfLoader.load(connection, from, data);
|
||||
const transaction = new Transaction().add({
|
||||
keys: [{pubkey: from.publicKey, isSigner: true}],
|
||||
keys: [{pubkey: from.publicKey, isSigner: true, isDebitable: true}],
|
||||
programId,
|
||||
});
|
||||
await sendAndConfirmTransaction(connection, transaction, from);
|
||||
@ -47,7 +47,7 @@ test('load BPF Rust program', async () => {
|
||||
);
|
||||
const programId = await BpfLoader.load(connection, from, data);
|
||||
const transaction = new Transaction().add({
|
||||
keys: [{pubkey: from.publicKey, isSigner: true}],
|
||||
keys: [{pubkey: from.publicKey, isSigner: true, isDebitable: true}],
|
||||
programId,
|
||||
});
|
||||
await sendAndConfirmTransaction(connection, transaction, from);
|
||||
|
@ -29,7 +29,7 @@ test('load native program', async () => {
|
||||
'solana_noop_program',
|
||||
);
|
||||
const transaction = new Transaction().add({
|
||||
keys: [{pubkey: from.publicKey, isSigner: true}],
|
||||
keys: [{pubkey: from.publicKey, isSigner: true, isDebitable: true}],
|
||||
programId,
|
||||
});
|
||||
|
||||
|
@ -93,73 +93,73 @@ test('parse wire format and serialize', () => {
|
||||
|
||||
const wireTransaction = Buffer.from([
|
||||
1,
|
||||
91,
|
||||
132,
|
||||
173,
|
||||
1,
|
||||
218,
|
||||
94,
|
||||
253,
|
||||
18,
|
||||
27,
|
||||
79,
|
||||
207,
|
||||
114,
|
||||
27,
|
||||
167,
|
||||
127,
|
||||
47,
|
||||
50,
|
||||
66,
|
||||
17,
|
||||
202,
|
||||
183,
|
||||
204,
|
||||
12,
|
||||
69,
|
||||
243,
|
||||
25,
|
||||
206,
|
||||
165,
|
||||
116,
|
||||
182,
|
||||
64,
|
||||
185,
|
||||
168,
|
||||
238,
|
||||
168,
|
||||
193,
|
||||
140,
|
||||
86,
|
||||
83,
|
||||
107,
|
||||
252,
|
||||
239,
|
||||
80,
|
||||
219,
|
||||
90,
|
||||
187,
|
||||
49,
|
||||
40,
|
||||
91,
|
||||
44,
|
||||
6,
|
||||
160,
|
||||
84,
|
||||
43,
|
||||
227,
|
||||
63,
|
||||
170,
|
||||
255,
|
||||
185,
|
||||
132,
|
||||
242,
|
||||
82,
|
||||
46,
|
||||
124,
|
||||
217,
|
||||
127,
|
||||
147,
|
||||
24,
|
||||
254,
|
||||
157,
|
||||
77,
|
||||
8,
|
||||
58,
|
||||
129,
|
||||
51,
|
||||
76,
|
||||
13,
|
||||
206,
|
||||
126,
|
||||
157,
|
||||
189,
|
||||
188,
|
||||
53,
|
||||
174,
|
||||
42,
|
||||
80,
|
||||
4,
|
||||
4,
|
||||
212,
|
||||
55,
|
||||
67,
|
||||
171,
|
||||
34,
|
||||
224,
|
||||
81,
|
||||
68,
|
||||
230,
|
||||
120,
|
||||
117,
|
||||
204,
|
||||
241,
|
||||
167,
|
||||
152,
|
||||
74,
|
||||
141,
|
||||
132,
|
||||
73,
|
||||
166,
|
||||
217,
|
||||
173,
|
||||
27,
|
||||
75,
|
||||
62,
|
||||
171,
|
||||
160,
|
||||
100,
|
||||
159,
|
||||
116,
|
||||
164,
|
||||
45,
|
||||
185,
|
||||
64,
|
||||
0,
|
||||
72,
|
||||
4,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
19,
|
||||
152,
|
||||
|
Reference in New Issue
Block a user