6262//! }
6363//! ```
6464
65- mod genesis_config;
66-
6765use std:: sync:: atomic:: { AtomicU64 , Ordering } ;
6866use std:: sync:: Arc ;
6967use std:: time:: Duration ;
@@ -76,8 +74,7 @@ use evolve_chain_index::{
7674 build_index_data, BlockMetadata , ChainIndex , ChainStateProvider , ChainStateProviderConfig ,
7775 PersistentChainIndex ,
7876} ;
79- use evolve_core:: runtime_api:: ACCOUNT_IDENTIFIER_PREFIX ;
80- use evolve_core:: { AccountId , Environment , Message , ReadonlyKV , SdkResult } ;
77+ use evolve_core:: { AccountId , ReadonlyKV } ;
8178use evolve_eth_jsonrpc:: { start_server_with_subscriptions, RpcServerConfig , SubscriptionManager } ;
8279use evolve_evnode:: { EvnodeServer , EvnodeServerConfig , ExecutorServiceConfig , OnBlockExecuted } ;
8380use evolve_mempool:: { new_shared_mempool, Mempool , SharedMempool } ;
@@ -92,6 +89,7 @@ use evolve_server::{
9289} ;
9390use evolve_stf_traits:: { AccountsCodeStorage , StateChange } ;
9491use evolve_storage:: { Operation , QmdbStorage , Storage , StorageConfig } ;
92+ use evolve_testapp:: genesis_config:: { EvdGenesisConfig , EvdGenesisResult } ;
9593use evolve_testapp:: {
9694 build_mempool_stf, default_gas_config, do_genesis_inner, install_account_codes,
9795 PLACEHOLDER_ACCOUNT ,
@@ -101,8 +99,6 @@ use evolve_token::account::TokenRef;
10199use evolve_tx_eth:: address_to_account_id;
102100use evolve_tx_eth:: TxContext ;
103101
104- use genesis_config:: { EvdGenesisConfig , EvdGenesisResult } ;
105-
106102#[ derive( Parser ) ]
107103#[ command( name = "evd" ) ]
108104#[ command( about = "Evolve node daemon with gRPC execution layer" ) ]
@@ -201,7 +197,7 @@ fn run_node(config: NodeConfig, genesis_config: Option<EvdGenesisConfig>) {
201197 }
202198 None => {
203199 tracing:: info!( "No existing state found, running genesis..." ) ;
204- let output = run_genesis ( & storage, & codes, genesis_config. as_ref ( ) ) . await ;
200+ let output = run_genesis ( & storage, & codes, genesis_config. as_ref ( ) ) ;
205201 commit_genesis ( & storage, output. changes , & output. genesis_result )
206202 . await
207203 . expect ( "genesis commit failed" ) ;
@@ -439,7 +435,7 @@ fn init_genesis(data_dir: &str, genesis_config: Option<EvdGenesisConfig>) {
439435 }
440436
441437 let codes = build_codes ( ) ;
442- let output = run_genesis ( & storage, & codes, genesis_config. as_ref ( ) ) . await ;
438+ let output = run_genesis ( & storage, & codes, genesis_config. as_ref ( ) ) ;
443439
444440 commit_genesis ( & storage, output. changes , & output. genesis_result )
445441 . await
@@ -457,48 +453,14 @@ fn build_codes() -> AccountStorageMock {
457453 codes
458454}
459455
460- /// Pre-register an EOA account in storage so genesis can reference it.
461- fn build_eoa_registration ( account_id : AccountId , eth_address : [ u8 ; 20 ] ) -> Vec < Operation > {
462- let mut ops = Vec :: with_capacity ( 3 ) ;
463-
464- // 1. Register account code identifier
465- let mut key = vec ! [ ACCOUNT_IDENTIFIER_PREFIX ] ;
466- key. extend_from_slice ( & account_id. as_bytes ( ) ) ;
467- let value = Message :: new ( & "EthEoaAccount" . to_string ( ) )
468- . unwrap ( )
469- . into_bytes ( )
470- . unwrap ( ) ;
471- ops. push ( Operation :: Set { key, value } ) ;
472-
473- // 2. Set nonce = 0 (Item prefix 0)
474- let mut nonce_key = account_id. as_bytes ( ) . to_vec ( ) ;
475- nonce_key. push ( 0u8 ) ;
476- let nonce_value = Message :: new ( & 0u64 ) . unwrap ( ) . into_bytes ( ) . unwrap ( ) ;
477- ops. push ( Operation :: Set {
478- key : nonce_key,
479- value : nonce_value,
480- } ) ;
481-
482- // 3. Set eth_address (Item prefix 1)
483- let mut addr_key = account_id. as_bytes ( ) . to_vec ( ) ;
484- addr_key. push ( 1u8 ) ;
485- let addr_value = Message :: new ( & eth_address) . unwrap ( ) . into_bytes ( ) . unwrap ( ) ;
486- ops. push ( Operation :: Set {
487- key : addr_key,
488- value : addr_value,
489- } ) ;
490-
491- ops
492- }
493-
494456/// Run genesis using the default testapp genesis or a custom genesis config.
495- async fn run_genesis < S : ReadonlyKV + Storage > (
457+ fn run_genesis < S : ReadonlyKV + Storage > (
496458 storage : & S ,
497459 codes : & AccountStorageMock ,
498460 genesis_config : Option < & EvdGenesisConfig > ,
499461) -> GenesisOutput < EvdGenesisResult > {
500462 match genesis_config {
501- Some ( config) => run_custom_genesis ( storage, codes, config) . await ,
463+ Some ( config) => run_custom_genesis ( storage, codes, config) ,
502464 None => run_default_genesis ( storage, codes) ,
503465 }
504466}
@@ -534,56 +496,29 @@ fn run_default_genesis<S: ReadonlyKV + Storage>(
534496}
535497
536498/// Custom genesis with ETH EOA accounts from a genesis JSON file.
537- async fn run_custom_genesis < S : ReadonlyKV + Storage > (
499+ ///
500+ /// Registers funded EOA accounts via `EthEoaAccountRef::initialize` inside
501+ /// `system_exec`, then initializes the token with their balances.
502+ fn run_custom_genesis < S : ReadonlyKV + Storage > (
538503 storage : & S ,
539504 codes : & AccountStorageMock ,
540505 genesis_config : & EvdGenesisConfig ,
541506) -> GenesisOutput < EvdGenesisResult > {
542507 use evolve_core:: BlockContext ;
508+ use evolve_testapp:: eth_eoa:: eth_eoa_account:: EthEoaAccountRef ;
543509
544- // Parse accounts that have a non-zero balance (need pre-registration for genesis funding).
545- // Other accounts are auto-registered by the STF on their first transaction.
546- let funded_accounts: Vec < ( Address , u128 ) > = genesis_config
510+ let funded_accounts: Vec < ( [ u8 ; 20 ] , u128 ) > = genesis_config
547511 . accounts
548512 . iter ( )
549513 . filter ( |acc| acc. balance > 0 )
550514 . map ( |acc| {
551515 let addr = acc
552516 . parse_address ( )
553517 . expect ( "invalid address in genesis config" ) ;
554- ( addr, acc. balance )
518+ ( addr. into_array ( ) , acc. balance )
555519 } )
556520 . collect ( ) ;
557521
558- // Pre-register only funded EOA accounts in storage
559- let mut pre_ops = Vec :: new ( ) ;
560- for ( addr, _) in & funded_accounts {
561- let id = address_to_account_id ( * addr) ;
562- let addr_bytes: [ u8 ; 20 ] = addr. into_array ( ) ;
563- pre_ops. extend ( build_eoa_registration ( id, addr_bytes) ) ;
564- }
565-
566- storage
567- . batch ( pre_ops)
568- . await
569- . expect ( "pre-register EOAs failed" ) ;
570- storage. commit ( ) . await . expect ( "pre-register commit failed" ) ;
571-
572- tracing:: info!(
573- "Pre-registered {} funded EOA accounts:" ,
574- funded_accounts. len( )
575- ) ;
576- for ( i, ( addr, balance) ) in funded_accounts. iter ( ) . enumerate ( ) {
577- let id = address_to_account_id ( * addr) ;
578- tracing:: info!( " #{:02}: {:?} (0x{:x}) balance={}" , i, id, addr, balance) ;
579- }
580-
581- // Build balances list for genesis token initialization
582- let balances: Vec < ( AccountId , u128 ) > = funded_accounts
583- . iter ( )
584- . map ( |( addr, balance) | ( address_to_account_id ( * addr) , * balance) )
585- . collect ( ) ;
586-
587522 let minter = AccountId :: new ( genesis_config. minter_id ) ;
588523 let metadata = genesis_config. token . to_metadata ( ) ;
589524
@@ -593,7 +528,27 @@ async fn run_custom_genesis<S: ReadonlyKV + Storage>(
593528
594529 let ( genesis_result, state) = stf
595530 . system_exec ( storage, codes, genesis_block, |env| {
596- do_custom_genesis ( metadata. clone ( ) , balances. clone ( ) , minter, env)
531+ for ( eth_addr, _) in & funded_accounts {
532+ EthEoaAccountRef :: initialize ( * eth_addr, env) ?;
533+ }
534+
535+ let balances: Vec < ( AccountId , u128 ) > = funded_accounts
536+ . iter ( )
537+ . map ( |( eth_addr, balance) | {
538+ let addr = Address :: from ( * eth_addr) ;
539+ ( address_to_account_id ( addr) , * balance)
540+ } )
541+ . collect ( ) ;
542+
543+ let token = TokenRef :: initialize ( metadata. clone ( ) , balances, Some ( minter) , env) ?. 0 ;
544+
545+ let scheduler_acc = SchedulerRef :: initialize ( vec ! [ ] , vec ! [ ] , env) ?. 0 ;
546+ scheduler_acc. update_begin_blockers ( vec ! [ ] , env) ?;
547+
548+ Ok ( EvdGenesisResult {
549+ token : token. 0 ,
550+ scheduler : scheduler_acc. 0 ,
551+ } )
597552 } )
598553 . expect ( "genesis failed" ) ;
599554
@@ -605,23 +560,6 @@ async fn run_custom_genesis<S: ReadonlyKV + Storage>(
605560 }
606561}
607562
608- fn do_custom_genesis (
609- metadata : evolve_fungible_asset:: FungibleAssetMetadata ,
610- balances : Vec < ( AccountId , u128 ) > ,
611- minter : AccountId ,
612- env : & mut dyn Environment ,
613- ) -> SdkResult < EvdGenesisResult > {
614- let token = TokenRef :: initialize ( metadata, balances, Some ( minter) , env) ?. 0 ;
615-
616- let scheduler_acc = SchedulerRef :: initialize ( vec ! [ ] , vec ! [ ] , env) ?. 0 ;
617- scheduler_acc. update_begin_blockers ( vec ! [ ] , env) ?;
618-
619- Ok ( EvdGenesisResult {
620- token : token. 0 ,
621- scheduler : scheduler_acc. 0 ,
622- } )
623- }
624-
625563fn compute_block_hash ( height : u64 , timestamp : u64 , parent_hash : B256 ) -> B256 {
626564 let mut data = Vec :: with_capacity ( 48 ) ;
627565 data. extend_from_slice ( & height. to_le_bytes ( ) ) ;
0 commit comments