-
Notifications
You must be signed in to change notification settings - Fork 197
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
disco/choreo: parsing, generating vote transactions; echoing vote tra…
…nsactions through gossip
- Loading branch information
1 parent
a165379
commit 998a6f3
Showing
9 changed files
with
691 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Oops, something went wrong.