feat: add Message.from method for decoding compiled messages (#11593)

This commit is contained in:
Jack May 2020-08-12 15:01:39 -07:00 committed by GitHub
parent be03731379
commit d4309b6481
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 43 deletions

View File

@ -53,6 +53,8 @@ type MessageArgs = {
instructions: CompiledInstruction[],
};
const PUBKEY_LENGTH = 32;
/**
* List of instructions to be processed atomically
*/
@ -167,4 +169,55 @@ export class Message {
instructionBuffer.copy(signData, length);
return signData.slice(0, length + instructionBuffer.length);
}
/**
* Decode a compiled message into a Message object.
*/
static from(buffer: Buffer | Uint8Array | Array<number>): Message {
// Slice up wire data
let byteArray = [...buffer];
const numRequiredSignatures = byteArray.shift();
const numReadonlySignedAccounts = byteArray.shift();
const numReadonlyUnsignedAccounts = byteArray.shift();
const accountCount = shortvec.decodeLength(byteArray);
let accountKeys = [];
for (let i = 0; i < accountCount; i++) {
const account = byteArray.slice(0, PUBKEY_LENGTH);
byteArray = byteArray.slice(PUBKEY_LENGTH);
accountKeys.push(bs58.encode(Buffer.from(account)));
}
const recentBlockhash = byteArray.slice(0, PUBKEY_LENGTH);
byteArray = byteArray.slice(PUBKEY_LENGTH);
const instructionCount = shortvec.decodeLength(byteArray);
let instructions = [];
for (let i = 0; i < instructionCount; i++) {
let instruction = {};
instruction.programIdIndex = byteArray.shift();
const accountCount = shortvec.decodeLength(byteArray);
instruction.accounts = byteArray.slice(0, accountCount);
byteArray = byteArray.slice(accountCount);
const dataLength = shortvec.decodeLength(byteArray);
const data = byteArray.slice(0, dataLength);
instruction.data = bs58.encode(Buffer.from(data));
byteArray = byteArray.slice(dataLength);
instructions.push(instruction);
}
const messageArgs = {
header: {
numRequiredSignatures,
numReadonlySignedAccounts,
numReadonlyUnsignedAccounts,
},
recentBlockhash: bs58.encode(Buffer.from(recentBlockhash)),
accountKeys,
instructions,
};
return new Message(messageArgs);
}
}

View File

@ -32,7 +32,6 @@ const DEFAULT_SIGNATURE = Buffer.alloc(64).fill(0);
*/
export const PACKET_DATA_SIZE = 1280 - 40 - 8;
const PUBKEY_LENGTH = 32;
const SIGNATURE_LENGTH = 64;
/**
@ -544,48 +543,7 @@ export class Transaction {
signatures.push(bs58.encode(Buffer.from(signature)));
}
const numRequiredSignatures = byteArray.shift();
const numReadonlySignedAccounts = byteArray.shift();
const numReadonlyUnsignedAccounts = byteArray.shift();
const accountCount = shortvec.decodeLength(byteArray);
let accountKeys = [];
for (let i = 0; i < accountCount; i++) {
const account = byteArray.slice(0, PUBKEY_LENGTH);
byteArray = byteArray.slice(PUBKEY_LENGTH);
accountKeys.push(bs58.encode(Buffer.from(account)));
}
const recentBlockhash = byteArray.slice(0, PUBKEY_LENGTH);
byteArray = byteArray.slice(PUBKEY_LENGTH);
const instructionCount = shortvec.decodeLength(byteArray);
let instructions = [];
for (let i = 0; i < instructionCount; i++) {
let instruction = {};
instruction.programIdIndex = byteArray.shift();
const accountCount = shortvec.decodeLength(byteArray);
instruction.accounts = byteArray.slice(0, accountCount);
byteArray = byteArray.slice(accountCount);
const dataLength = shortvec.decodeLength(byteArray);
const data = byteArray.slice(0, dataLength);
instruction.data = bs58.encode(Buffer.from(data));
byteArray = byteArray.slice(dataLength);
instructions.push(instruction);
}
const messageArgs = {
header: {
numRequiredSignatures,
numReadonlySignedAccounts,
numReadonlyUnsignedAccounts,
},
recentBlockhash: bs58.encode(Buffer.from(recentBlockhash)),
accountKeys,
instructions,
};
return Transaction.populate(new Message(messageArgs), signatures);
return Transaction.populate(Message.from(byteArray), signatures);
}
/**