From c929516f521d2bae77b1cf61635475a9fdc58211 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Tue, 23 Jul 2019 18:06:55 -0700 Subject: [PATCH] feat: add vote account decoder (#418) --- web3.js/module.flow.js | 25 +++++++++++ web3.js/src/index.js | 1 + web3.js/src/vote-account.js | 85 +++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 web3.js/src/vote-account.js diff --git a/web3.js/module.flow.js b/web3.js/module.flow.js index 50c6f4e43..32eca0075 100644 --- a/web3.js/module.flow.js +++ b/web3.js/module.flow.js @@ -158,6 +158,31 @@ declare module '@solana/web3.js' { static fromConfigData(buffer: Buffer): ?ValidatorInfo; } + // === src/vote-account.js === + declare export type Lockout = {| + slot: number, + confirmationCount: number, + |}; + + declare export type EpochCredits = {| + epoch: number, + credits: number, + prevCredits: number, + |}; + + declare export class VoteAccount { + votes: Array; + nodePubkey: PublicKey; + authorizedVoterPubkey: PublicKey; + commission: number; + rootSlot: number | null; + epoch: number; + credits: number; + lastEpochCredits: number; + epochCredits: Array; + static fromAccountData(buffer: Buffer): VoteAccount; + } + // === src/transaction.js === declare export type TransactionSignature = string; diff --git a/web3.js/src/index.js b/web3.js/src/index.js index 0dcc62cc2..05e25fb47 100644 --- a/web3.js/src/index.js +++ b/web3.js/src/index.js @@ -9,6 +9,7 @@ export {SystemProgram} from './system-program'; export {Token, TokenAmount} from './token-program'; export {Transaction, TransactionInstruction} from './transaction'; export {ValidatorInfo} from './validator-info'; +export {VoteAccount} from './vote-account'; export {sendAndConfirmTransaction} from './util/send-and-confirm-transaction'; export { sendAndConfirmRawTransaction, diff --git a/web3.js/src/vote-account.js b/web3.js/src/vote-account.js new file mode 100644 index 000000000..ca523c541 --- /dev/null +++ b/web3.js/src/vote-account.js @@ -0,0 +1,85 @@ +// @flow +import * as BufferLayout from 'buffer-layout'; + +import * as Layout from './layout'; +import {PublicKey} from './publickey'; + +export type Lockout = {| + slot: number, + confirmationCount: number, +|}; + +/** + * History of how many credits earned by the end of each epoch + */ +export type EpochCredits = {| + epoch: number, + credits: number, + prevCredits: number, +|}; + +/** + * See https://github.com/solana-labs/solana/blob/8a12ed029cfa38d4a45400916c2463fb82bbec8c/programs/vote_api/src/vote_state.rs#L68-L88 + * + * @private + */ +const VoteAccountLayout = BufferLayout.struct([ + BufferLayout.nu64(), // votes.length + BufferLayout.seq( + BufferLayout.struct([ + BufferLayout.nu64('slot'), + BufferLayout.u32('confirmationCount'), + ]), + BufferLayout.offset(BufferLayout.u32(), -8), + 'votes', + ), + Layout.publicKey('nodePubkey'), + Layout.publicKey('authorizedVoterPubkey'), + BufferLayout.u8('commission'), + BufferLayout.u8('rootSlotValid'), + BufferLayout.nu64('rootSlot'), + BufferLayout.nu64('epoch'), + BufferLayout.nu64('credits'), + BufferLayout.nu64('lastEpochCredits'), + BufferLayout.nu64(), // epochCredits.length + BufferLayout.seq( + BufferLayout.struct([ + BufferLayout.nu64('epoch'), + BufferLayout.nu64('credits'), + BufferLayout.nu64('prevCredits'), + ]), + BufferLayout.offset(BufferLayout.u32(), -8), + 'epochCredits', + ), +]); + +/** + * VoteAccount class + */ +export class VoteAccount { + votes: Array; + nodePubkey: PublicKey; + authorizedVoterPubkey: PublicKey; + commission: number; + rootSlot: number | null; + epoch: number; + credits: number; + lastEpochCredits: number; + epochCredits: Array; + + /** + * Deserialize VoteAccount from the account data. + * + * @param buffer account data + * @return VoteAccount + */ + static fromAccountData(buffer: Buffer): VoteAccount { + const va = VoteAccountLayout.decode(buffer, 0); + va.nodePubkey = new PublicKey(va.nodePubkey); + va.authorizedVoterPubkey = new PublicKey(va.authorizedVoterPubkey); + if (!va.rootSlotValid) { + va.rootSlot = null; + } + return va; + } +}