Skip to content

Commit

Permalink
disco/choreo: parsing, generating vote transactions; echoing vote tra…
Browse files Browse the repository at this point in the history
…nsactions through gossip
  • Loading branch information
yhzhangjump authored and arjain4 committed May 30, 2024
1 parent a165379 commit 998a6f3
Show file tree
Hide file tree
Showing 9 changed files with 691 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/choreo/fd_choreo.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
#include "commitment/fd_commitment.h" /* Includes fd_choreo_base.h */
#include "forks/fd_forks.h" /* Includes fd_choreo_base.h */
#include "ghost/fd_ghost.h" /* Includes fd_choreo_base.h */
#include "vote/fd_vote.h" /* Includes fd_choreo_base.h */

#endif /* HEADER_fd_src_choreo_fd_choreo_h */
5 changes: 5 additions & 0 deletions src/choreo/vote/Local.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ifdef FD_HAS_INT128
$(call add-hdrs,fd_vote.h)
$(call add-objs,fd_vote,fd_choreo)
$(call make-unit-test,test_choreo_vote,test_choreo_vote,fd_disco fd_choreo fd_flamenco fd_funk fd_tango fd_util fd_ballet fd_reedsol fd_waltz,$(SECP256K1_LIBS))
endif
117 changes: 117 additions & 0 deletions src/choreo/vote/fd_vote.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#include "fd_vote.h"

#pragma GCC diagnostic ignored "-Wformat"
#pragma GCC diagnostic ignored "-Wformat-extra-args"

ulong
fd_vote_txn_generate(fd_compact_vote_state_update_t* compact_vote_update,
fd_pubkey_t* validator_pubkey,
fd_pubkey_t* vote_acct_pubkey,
uchar* validator_privkey,
uchar* vote_acct_privkey,
uchar* recent_blockhash,
uchar out_txn_meta_buf [static FD_TXN_MAX_SZ],
uchar out_txn_buf [static FD_TXN_MTU]
) {
/* Create the transaction base */
fd_pubkey_t pubkeys[2], vote_program_pubkey;
memcpy( pubkeys, validator_pubkey, sizeof(fd_pubkey_t) );
memcpy( pubkeys + 1, vote_acct_pubkey, sizeof(fd_pubkey_t) );
memcpy( &vote_program_pubkey, &fd_solana_vote_program_id, sizeof(fd_pubkey_t) );

fd_txn_accounts_t vote_txn_accounts;
vote_txn_accounts.signature_cnt = 2;
vote_txn_accounts.readonly_signed_cnt = 0;
vote_txn_accounts.readonly_unsigned_cnt = 1;
vote_txn_accounts.acct_cnt = 3; /* 3 accounts: validator, vote account, vote program */
vote_txn_accounts.signers_w = pubkeys; /* 2 signers: validator, vote account */
vote_txn_accounts.signers_r = NULL;
vote_txn_accounts.non_signers_w = NULL;
vote_txn_accounts.non_signers_r = &vote_program_pubkey; /* 1 non-signer: vote program */
FD_TEST( fd_txn_base_generate( out_txn_meta_buf, out_txn_buf, 2, &vote_txn_accounts, recent_blockhash ) );

/* Add the vote instruction to the transaction */
fd_vote_instruction_t vote_instr;
uchar vote_instr_buf[FD_TXN_MTU];
vote_instr.discriminant = fd_vote_instruction_enum_compact_update_vote_state;
vote_instr.inner.compact_update_vote_state = *compact_vote_update;
fd_bincode_encode_ctx_t encode = { .data = vote_instr_buf, .dataend = (vote_instr_buf + FD_TXN_MTU) };
fd_vote_instruction_encode ( &vote_instr, &encode );
ushort vote_instr_size = (ushort)fd_vote_instruction_size( &vote_instr );

uchar instr_accounts[2];
instr_accounts[0] = 1; /* vote account */
instr_accounts[1] = 1; /* vote authority */
uchar program_id = 2; /* vote program */
ulong txn_size = fd_txn_add_instr(out_txn_meta_buf,
out_txn_buf,
program_id,
instr_accounts,
2, /* 2 accounts in instr_accounts */
vote_instr_buf,
vote_instr_size);

/* Add the signatures of validator and vote account */
fd_sha512_t sha;
fd_txn_t * txn_meta = (fd_txn_t *) fd_type_pun( out_txn_meta_buf );
fd_ed25519_sign( /* sig */ out_txn_buf + txn_meta->signature_off,
/* msg */ out_txn_buf + txn_meta->message_off,
/* sz */ txn_size - txn_meta->message_off,
/* public_key */ validator_pubkey->key,
/* private_key */ validator_privkey,
&sha);
fd_ed25519_sign( /* sig */ out_txn_buf + txn_meta->signature_off + FD_TXN_SIGNATURE_SZ,
/* msg */ out_txn_buf + txn_meta->message_off,
/* sz */ txn_size - txn_meta->message_off,
/* public_key */ vote_acct_pubkey->key,
/* private_key */ vote_acct_privkey,
&sha);

return txn_size;
}

int
fd_vote_txn_parse(uchar txn_buf [static FD_TXN_MTU],
ulong txn_size,
fd_valloc_t valloc,
fd_compact_vote_state_update_t *out_compact_vote_update){
uchar out_buf[ FD_TXN_MAX_SZ ];
fd_txn_t * parsed_txn = (fd_txn_t *)fd_type_pun( out_buf );
ulong out_sz = fd_txn_parse( txn_buf, txn_size, out_buf, NULL );
FD_TEST( out_sz );
FD_TEST( parsed_txn );
FD_TEST( parsed_txn->instr_cnt == 1);

uchar program_id = parsed_txn->instr[0].program_id;
uchar* program_account_addr = (txn_buf + parsed_txn->acct_addr_off
+ FD_TXN_ACCT_ADDR_SZ * program_id );

if ( memcmp( program_account_addr, fd_solana_vote_program_id.key, sizeof( fd_pubkey_t ) ) ) {
FD_LOG_WARNING( ("fd_vote_txn_parse: txn targets program %32J instead of %32J",
program_account_addr,
fd_solana_vote_program_id.key) );
return FD_VOTE_TXN_PARSE_ERR_WRONG_PROG;
} else {
fd_vote_instruction_t vote_instr = { 0 };
ushort instr_data_sz = parsed_txn->instr[0].data_sz;
uchar* instr_data = txn_buf + parsed_txn->instr[0].data_off;
fd_bincode_decode_ctx_t decode = {
.data = instr_data,
.dataend = instr_data + instr_data_sz,
.valloc = valloc
};
int decode_result = fd_vote_instruction_decode( &vote_instr, &decode );
if( decode_result != FD_BINCODE_SUCCESS) {
FD_LOG_WARNING(("fd_vote_txn_parse: fail at decoding vote instruction"));
return FD_VOTE_TXN_PARSE_ERR_BAD_INST;
} else {
if (vote_instr.discriminant != fd_vote_instruction_enum_compact_update_vote_state) {
FD_LOG_WARNING(("fd_vote_txn_parse: not compact_update_vote_state instruction"));
return FD_VOTE_TXN_PARSE_ERR_BAD_INST;
} else {
*out_compact_vote_update = vote_instr.inner.compact_update_vote_state;
}
}
}
return FD_VOTE_TXN_PARSE_OK;
}
28 changes: 28 additions & 0 deletions src/choreo/vote/fd_vote.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef HEADER_fd_src_choreo_vote_fd_vote_h
#define HEADER_fd_src_choreo_vote_fd_vote_h

#include "../fd_choreo_base.h"
#include "../../flamenco/txn/fd_txn_generate.h"
#include "../../flamenco/runtime/fd_system_ids.h"

#define FD_VOTE_TXN_PARSE_OK 0
#define FD_VOTE_TXN_PARSE_ERR_BAD_INST -1
#define FD_VOTE_TXN_PARSE_ERR_WRONG_PROG -2

ulong
fd_vote_txn_generate(fd_compact_vote_state_update_t *vote_update,
fd_pubkey_t *valicator_pubkey,
fd_pubkey_t *vote_acct_pubkey,
uchar* valicator_privkey,
uchar* vote_acct_privkey,
uchar* recent_blockhash,
uchar out_txn_meta_buf [static FD_TXN_MAX_SZ],
uchar out_txn_buf [static FD_TXN_MTU]);

int
fd_vote_txn_parse(uchar txn_buf [static FD_TXN_MTU],
ulong txn_size,
fd_valloc_t valloc,
fd_compact_vote_state_update_t *out_vote_update);

#endif
66 changes: 66 additions & 0 deletions src/choreo/vote/test_choreo_vote.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include <sys/random.h>
#include "../../util/fd_util.h"
#include "../../choreo/fd_choreo.h"
#include "../../ballet/ed25519/fd_ed25519.h"
#include "../../flamenco/fd_flamenco.h"
#include "../../flamenco/txn/fd_txn_generate.h"
#include "../../flamenco/runtime/fd_system_ids.h"

#pragma GCC diagnostic ignored "-Wformat"
#pragma GCC diagnostic ignored "-Wformat-extra-args"

#define TEST_VOTE_TXN_MAGIC (0x7e58UL)

int
main( int argc, char ** argv ) {
fd_boot( &argc, &argv );
fd_flamenco_boot( &argc, &argv );

/* keys */
fd_sha512_t sha[2];
fd_pubkey_t vote_acct_pubkey, validator_pubkey;
uchar vote_acct_privkey[32], validator_privkey[32];

FD_TEST( 32UL == getrandom( vote_acct_privkey, 32UL, 0 ) );
FD_TEST( 32UL == getrandom( validator_privkey, 32UL, 0 ) );
FD_TEST( fd_ed25519_public_from_private( vote_acct_pubkey.key, vote_acct_privkey, &sha[0] ) );
FD_TEST( fd_ed25519_public_from_private( validator_pubkey.key, validator_privkey, &sha[1] ) );

/* workspace */
ulong page_cnt = 1;
char * _page_sz = "gigantic";
ulong numa_idx = fd_shmem_numa_idx( 0 );
fd_wksp_t * wksp = fd_wksp_new_anonymous(
fd_cstr_to_shmem_page_sz( _page_sz ), page_cnt, fd_shmem_cpu_idx( numa_idx ), "wksp", 0UL );
FD_TEST( wksp );

/* alloc */
void * alloc_shmem =
fd_wksp_alloc_laddr( wksp, fd_alloc_align(), fd_alloc_footprint(), TEST_VOTE_TXN_MAGIC );
void * alloc_shalloc = fd_alloc_new( alloc_shmem, TEST_VOTE_TXN_MAGIC );
fd_alloc_t * alloc = fd_alloc_join( alloc_shalloc, 0UL );
fd_valloc_t valloc = fd_alloc_virtual( alloc );

/* create compact_vote_state_update with dummy values */
fd_compact_vote_state_update_t compact_vote_update;
memset( &compact_vote_update, 0, sizeof(fd_compact_vote_state_update_t) );
compact_vote_update.root = 100;
compact_vote_update.lockouts_len = 0;
static ulong now = 1715701506716580798UL;
compact_vote_update.timestamp = &now;
FD_TEST( 32UL == getrandom( compact_vote_update.hash.key, 32UL, 0 ) );

/* create the vote transaction */
uchar txn_meta_buf[ FD_TXN_MAX_SZ ];
uchar txn_buf [ FD_TXN_MTU ];
uchar *recent_blockhash = NULL;
ulong txn_size = fd_vote_txn_generate( &compact_vote_update, &validator_pubkey, &vote_acct_pubkey, validator_privkey, vote_acct_privkey, recent_blockhash, txn_meta_buf, txn_buf);
FD_LOG_NOTICE(("fd_vote_txn_generate: vote txn has %lu bytes", txn_size));

/* parse the transaction back */
fd_compact_vote_state_update_t parsed_vote_update;
FD_TEST( FD_VOTE_TXN_PARSE_OK == fd_vote_txn_parse(txn_buf, txn_size, valloc, &parsed_vote_update) );
FD_LOG_NOTICE((".root: %ld == %ld", compact_vote_update.root, parsed_vote_update.root));
FD_LOG_NOTICE((".timestamp: %lu == %lu", *compact_vote_update.timestamp, *parsed_vote_update.timestamp));
FD_LOG_NOTICE((".hash: %32J == %32J", compact_vote_update.hash.key, parsed_vote_update.hash.key));
}
1 change: 1 addition & 0 deletions src/disco/consensus/Local.mk
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
ifdef FD_HAS_INT128
$(call make-unit-test,test_consensus,test_consensus,fd_disco fd_choreo fd_flamenco fd_funk fd_tango fd_util fd_ballet fd_reedsol fd_waltz,$(SECP256K1_LIBS))
$(call make-unit-test,test_gossip_echo_vote,test_gossip_echo_vote,fd_disco fd_choreo fd_flamenco fd_funk fd_tango fd_util fd_ballet fd_reedsol fd_waltz,$(SECP256K1_LIBS))
endif
Loading

0 comments on commit 998a6f3

Please sign in to comment.