UNPKG

@bbachain/web3.js

Version:

BBAChain Javascript API

237 lines (214 loc) 5.84 kB
import * as BufferLayout from '@bbachain/buffer-layout'; import type {Buffer} from 'buffer'; import * as Layout from './layout'; import {PublicKey} from './publickey'; import {toBuffer} from './utils/to-buffer'; export const VOTE_PROGRAM_ID = new PublicKey( 'Vote111111111111111111111111111111111111111', ); export type Lockout = { slot: number; confirmationCount: number; }; /** * History of how many credits earned by the end of each epoch */ export type EpochCredits = Readonly<{ epoch: number; credits: number; prevCredits: number; }>; export type AuthorizedVoter = Readonly<{ epoch: number; authorizedVoter: PublicKey; }>; type AuthorizedVoterRaw = Readonly<{ authorizedVoter: Uint8Array; epoch: number; }>; type PriorVoters = Readonly<{ buf: PriorVoterRaw[]; idx: number; isEmpty: number; }>; export type PriorVoter = Readonly<{ authorizedPubkey: PublicKey; epochOfLastAuthorizedSwitch: number; targetEpoch: number; }>; type PriorVoterRaw = Readonly<{ authorizedPubkey: Uint8Array; epochOfLastAuthorizedSwitch: number; targetEpoch: number; }>; export type BlockTimestamp = Readonly<{ slot: number; timestamp: number; }>; type VoteAccountData = Readonly<{ authorizedVoters: AuthorizedVoterRaw[]; authorizedWithdrawer: Uint8Array; commission: number; epochCredits: EpochCredits[]; lastTimestamp: BlockTimestamp; nodePubkey: Uint8Array; priorVoters: PriorVoters; rootSlot: number; rootSlotValid: number; votes: Lockout[]; }>; /** * See https://github.com/solana-labs/solana/blob/8a12ed029cfa38d4a45400916c2463fb82bbec8c/programs/vote_api/src/vote_state.rs#L68-L88 * * @internal */ const VoteAccountLayout = BufferLayout.struct<VoteAccountData>([ Layout.publicKey('nodePubkey'), Layout.publicKey('authorizedWithdrawer'), BufferLayout.u8('commission'), BufferLayout.nu64(), // votes.length BufferLayout.seq<Lockout>( BufferLayout.struct([ BufferLayout.nu64('slot'), BufferLayout.u32('confirmationCount'), ]), BufferLayout.offset(BufferLayout.u32(), -8), 'votes', ), BufferLayout.u8('rootSlotValid'), BufferLayout.nu64('rootSlot'), BufferLayout.nu64(), // authorizedVoters.length BufferLayout.seq<AuthorizedVoterRaw>( BufferLayout.struct([ BufferLayout.nu64('epoch'), Layout.publicKey('authorizedVoter'), ]), BufferLayout.offset(BufferLayout.u32(), -8), 'authorizedVoters', ), BufferLayout.struct<PriorVoters>( [ BufferLayout.seq( BufferLayout.struct([ Layout.publicKey('authorizedPubkey'), BufferLayout.nu64('epochOfLastAuthorizedSwitch'), BufferLayout.nu64('targetEpoch'), ]), 32, 'buf', ), BufferLayout.nu64('idx'), BufferLayout.u8('isEmpty'), ], 'priorVoters', ), BufferLayout.nu64(), // epochCredits.length BufferLayout.seq<EpochCredits>( BufferLayout.struct([ BufferLayout.nu64('epoch'), BufferLayout.nu64('credits'), BufferLayout.nu64('prevCredits'), ]), BufferLayout.offset(BufferLayout.u32(), -8), 'epochCredits', ), BufferLayout.struct<BlockTimestamp>( [BufferLayout.nu64('slot'), BufferLayout.nu64('timestamp')], 'lastTimestamp', ), ]); type VoteAccountArgs = { nodePubkey: PublicKey; authorizedWithdrawer: PublicKey; commission: number; rootSlot: number | null; votes: Lockout[]; authorizedVoters: AuthorizedVoter[]; priorVoters: PriorVoter[]; epochCredits: EpochCredits[]; lastTimestamp: BlockTimestamp; }; /** * VoteAccount class */ export class VoteAccount { nodePubkey: PublicKey; authorizedWithdrawer: PublicKey; commission: number; rootSlot: number | null; votes: Lockout[]; authorizedVoters: AuthorizedVoter[]; priorVoters: PriorVoter[]; epochCredits: EpochCredits[]; lastTimestamp: BlockTimestamp; /** * @internal */ constructor(args: VoteAccountArgs) { this.nodePubkey = args.nodePubkey; this.authorizedWithdrawer = args.authorizedWithdrawer; this.commission = args.commission; this.rootSlot = args.rootSlot; this.votes = args.votes; this.authorizedVoters = args.authorizedVoters; this.priorVoters = args.priorVoters; this.epochCredits = args.epochCredits; this.lastTimestamp = args.lastTimestamp; } /** * Deserialize VoteAccount from the account data. * * @param buffer account data * @return VoteAccount */ static fromAccountData( buffer: Buffer | Uint8Array | Array<number>, ): VoteAccount { const versionOffset = 4; const va = VoteAccountLayout.decode(toBuffer(buffer), versionOffset); let rootSlot: number | null = va.rootSlot; if (!va.rootSlotValid) { rootSlot = null; } return new VoteAccount({ nodePubkey: new PublicKey(va.nodePubkey), authorizedWithdrawer: new PublicKey(va.authorizedWithdrawer), commission: va.commission, votes: va.votes, rootSlot, authorizedVoters: va.authorizedVoters.map(parseAuthorizedVoter), priorVoters: getPriorVoters(va.priorVoters), epochCredits: va.epochCredits, lastTimestamp: va.lastTimestamp, }); } } function parseAuthorizedVoter({ authorizedVoter, epoch, }: AuthorizedVoterRaw): AuthorizedVoter { return { epoch, authorizedVoter: new PublicKey(authorizedVoter), }; } function parsePriorVoters({ authorizedPubkey, epochOfLastAuthorizedSwitch, targetEpoch, }: PriorVoterRaw): PriorVoter { return { authorizedPubkey: new PublicKey(authorizedPubkey), epochOfLastAuthorizedSwitch, targetEpoch, }; } function getPriorVoters({buf, idx, isEmpty}: PriorVoters): PriorVoter[] { if (isEmpty) { return []; } return [ ...buf.slice(idx + 1).map(parsePriorVoters), ...buf.slice(0, idx).map(parsePriorVoters), ]; }