@@ -14,11 +14,13 @@ mod new_testnet;
14
14
mod parse_ssz;
15
15
mod replace_state_pubkeys;
16
16
mod skip_slots;
17
+ mod state_root;
17
18
mod transition_blocks;
18
19
19
20
use clap:: { App , Arg , ArgMatches , SubCommand } ;
20
- use clap_utils:: parse_path_with_default_in_home_dir ;
21
+ use clap_utils:: parse_optional ;
21
22
use environment:: { EnvironmentBuilder , LoggerConfig } ;
23
+ use eth2_network_config:: Eth2NetworkConfig ;
22
24
use parse_ssz:: run_parse_ssz;
23
25
use std:: path:: PathBuf ;
24
26
use std:: process;
@@ -49,7 +51,16 @@ fn main() {
49
51
. value_name ( "PATH" )
50
52
. takes_value ( true )
51
53
. global ( true )
52
- . help ( "The testnet dir. Defaults to ~/.lighthouse/testnet" ) ,
54
+ . help ( "The testnet dir." ) ,
55
+ )
56
+ . arg (
57
+ Arg :: with_name ( "network" )
58
+ . long ( "network" )
59
+ . value_name ( "NAME" )
60
+ . takes_value ( true )
61
+ . global ( true )
62
+ . help ( "The network to use. Defaults to mainnet." )
63
+ . conflicts_with ( "testnet-dir" )
53
64
)
54
65
. subcommand (
55
66
SubCommand :: with_name ( "skip-slots" )
@@ -125,7 +136,7 @@ fn main() {
125
136
. takes_value ( true )
126
137
. conflicts_with ( "beacon-url" )
127
138
. requires ( "block-path" )
128
- . help ( "Path to load a BeaconState from file as SSZ." ) ,
139
+ . help ( "Path to load a BeaconState from as SSZ." ) ,
129
140
)
130
141
. arg (
131
142
Arg :: with_name ( "block-path" )
@@ -134,7 +145,7 @@ fn main() {
134
145
. takes_value ( true )
135
146
. conflicts_with ( "beacon-url" )
136
147
. requires ( "pre-state-path" )
137
- . help ( "Path to load a SignedBeaconBlock from file as SSZ." ) ,
148
+ . help ( "Path to load a SignedBeaconBlock from as SSZ." ) ,
138
149
)
139
150
. arg (
140
151
Arg :: with_name ( "post-state-output-path" )
@@ -761,14 +772,14 @@ fn main() {
761
772
)
762
773
. subcommand (
763
774
SubCommand :: with_name ( "block-root" )
764
- . about ( "Computes the block root of some block" )
775
+ . about ( "Computes the block root of some block. " )
765
776
. arg (
766
777
Arg :: with_name ( "block-path" )
767
778
. long ( "block-path" )
768
779
. value_name ( "PATH" )
769
780
. takes_value ( true )
770
781
. conflicts_with ( "beacon-url" )
771
- . help ( "Path to load a SignedBeaconBlock from file as SSZ." ) ,
782
+ . help ( "Path to load a SignedBeaconBlock from as SSZ." ) ,
772
783
)
773
784
. arg (
774
785
Arg :: with_name ( "beacon-url" )
@@ -794,6 +805,41 @@ fn main() {
794
805
. help ( "Number of repeat runs, useful for benchmarking." ) ,
795
806
)
796
807
)
808
+ . subcommand (
809
+ SubCommand :: with_name ( "state-root" )
810
+ . about ( "Computes the state root of some state." )
811
+ . arg (
812
+ Arg :: with_name ( "state-path" )
813
+ . long ( "state-path" )
814
+ . value_name ( "PATH" )
815
+ . takes_value ( true )
816
+ . conflicts_with ( "beacon-url" )
817
+ . help ( "Path to load a BeaconState from as SSZ." ) ,
818
+ )
819
+ . arg (
820
+ Arg :: with_name ( "beacon-url" )
821
+ . long ( "beacon-url" )
822
+ . value_name ( "URL" )
823
+ . takes_value ( true )
824
+ . help ( "URL to a beacon-API provider." ) ,
825
+ )
826
+ . arg (
827
+ Arg :: with_name ( "state-id" )
828
+ . long ( "state-id" )
829
+ . value_name ( "BLOCK_ID" )
830
+ . takes_value ( true )
831
+ . requires ( "beacon-url" )
832
+ . help ( "Identifier for a state as per beacon-API standards (slot, root, etc.)" ) ,
833
+ )
834
+ . arg (
835
+ Arg :: with_name ( "runs" )
836
+ . long ( "runs" )
837
+ . value_name ( "INTEGER" )
838
+ . takes_value ( true )
839
+ . default_value ( "1" )
840
+ . help ( "Number of repeat runs, useful for benchmarking." ) ,
841
+ )
842
+ )
797
843
. get_matches ( ) ;
798
844
799
845
let result = matches
@@ -840,17 +886,44 @@ fn run<T: EthSpec>(
840
886
. build ( )
841
887
. map_err ( |e| format ! ( "should build env: {:?}" , e) ) ?;
842
888
843
- let testnet_dir = parse_path_with_default_in_home_dir (
844
- matches,
845
- "testnet-dir" ,
846
- PathBuf :: from ( directory:: DEFAULT_ROOT_DIR ) . join ( "testnet" ) ,
847
- ) ?;
889
+ // Determine testnet-dir path or network name depending on CLI flags.
890
+ let ( testnet_dir, network_name) =
891
+ if let Some ( testnet_dir) = parse_optional :: < PathBuf > ( matches, "testnet-dir" ) ? {
892
+ ( Some ( testnet_dir) , None )
893
+ } else {
894
+ let network_name =
895
+ parse_optional ( matches, "network" ) ?. unwrap_or_else ( || "mainnet" . to_string ( ) ) ;
896
+ ( None , Some ( network_name) )
897
+ } ;
898
+
899
+ // Lazily load either the testnet dir or the network config, as required.
900
+ // Some subcommands like new-testnet need the testnet dir but not the network config.
901
+ let get_testnet_dir = || testnet_dir. clone ( ) . ok_or ( "testnet-dir is required" ) ;
902
+ let get_network_config = || {
903
+ if let Some ( testnet_dir) = & testnet_dir {
904
+ Eth2NetworkConfig :: load ( testnet_dir. clone ( ) ) . map_err ( |e| {
905
+ format ! (
906
+ "Unable to open testnet dir at {}: {}" ,
907
+ testnet_dir. display( ) ,
908
+ e
909
+ )
910
+ } )
911
+ } else {
912
+ let network_name = network_name. ok_or ( "no network name or testnet-dir provided" ) ?;
913
+ Eth2NetworkConfig :: constant ( & network_name) ?. ok_or ( "invalid network name" . into ( ) )
914
+ }
915
+ } ;
848
916
849
917
match matches. subcommand ( ) {
850
- ( "transition-blocks" , Some ( matches) ) => transition_blocks:: run :: < T > ( env, matches)
851
- . map_err ( |e| format ! ( "Failed to transition blocks: {}" , e) ) ,
918
+ ( "transition-blocks" , Some ( matches) ) => {
919
+ let network_config = get_network_config ( ) ?;
920
+ transition_blocks:: run :: < T > ( env, network_config, matches)
921
+ . map_err ( |e| format ! ( "Failed to transition blocks: {}" , e) )
922
+ }
852
923
( "skip-slots" , Some ( matches) ) => {
853
- skip_slots:: run :: < T > ( env, matches) . map_err ( |e| format ! ( "Failed to skip slots: {}" , e) )
924
+ let network_config = get_network_config ( ) ?;
925
+ skip_slots:: run :: < T > ( env, network_config, matches)
926
+ . map_err ( |e| format ! ( "Failed to skip slots: {}" , e) )
854
927
}
855
928
( "pretty-ssz" , Some ( matches) ) => {
856
929
run_parse_ssz :: < T > ( matches) . map_err ( |e| format ! ( "Failed to pretty print hex: {}" , e) )
@@ -859,22 +932,33 @@ fn run<T: EthSpec>(
859
932
deploy_deposit_contract:: run :: < T > ( env, matches)
860
933
. map_err ( |e| format ! ( "Failed to run deploy-deposit-contract command: {}" , e) )
861
934
}
862
- ( "eth1-genesis" , Some ( matches) ) => eth1_genesis:: run :: < T > ( env, testnet_dir, matches)
863
- . map_err ( |e| format ! ( "Failed to run eth1-genesis command: {}" , e) ) ,
864
- ( "interop-genesis" , Some ( matches) ) => interop_genesis:: run :: < T > ( testnet_dir, matches)
865
- . map_err ( |e| format ! ( "Failed to run interop-genesis command: {}" , e) ) ,
935
+ ( "eth1-genesis" , Some ( matches) ) => {
936
+ let testnet_dir = get_testnet_dir ( ) ?;
937
+ eth1_genesis:: run :: < T > ( env, testnet_dir, matches)
938
+ . map_err ( |e| format ! ( "Failed to run eth1-genesis command: {}" , e) )
939
+ }
940
+ ( "interop-genesis" , Some ( matches) ) => {
941
+ let testnet_dir = get_testnet_dir ( ) ?;
942
+ interop_genesis:: run :: < T > ( testnet_dir, matches)
943
+ . map_err ( |e| format ! ( "Failed to run interop-genesis command: {}" , e) )
944
+ }
866
945
( "change-genesis-time" , Some ( matches) ) => {
946
+ let testnet_dir = get_testnet_dir ( ) ?;
867
947
change_genesis_time:: run :: < T > ( testnet_dir, matches)
868
948
. map_err ( |e| format ! ( "Failed to run change-genesis-time command: {}" , e) )
869
949
}
870
950
( "create-payload-header" , Some ( matches) ) => create_payload_header:: run :: < T > ( matches)
871
951
. map_err ( |e| format ! ( "Failed to run create-payload-header command: {}" , e) ) ,
872
952
( "replace-state-pubkeys" , Some ( matches) ) => {
953
+ let testnet_dir = get_testnet_dir ( ) ?;
873
954
replace_state_pubkeys:: run :: < T > ( testnet_dir, matches)
874
955
. map_err ( |e| format ! ( "Failed to run replace-state-pubkeys command: {}" , e) )
875
956
}
876
- ( "new-testnet" , Some ( matches) ) => new_testnet:: run :: < T > ( testnet_dir, matches)
877
- . map_err ( |e| format ! ( "Failed to run new_testnet command: {}" , e) ) ,
957
+ ( "new-testnet" , Some ( matches) ) => {
958
+ let testnet_dir = get_testnet_dir ( ) ?;
959
+ new_testnet:: run :: < T > ( testnet_dir, matches)
960
+ . map_err ( |e| format ! ( "Failed to run new_testnet command: {}" , e) )
961
+ }
878
962
( "check-deposit-data" , Some ( matches) ) => check_deposit_data:: run ( matches)
879
963
. map_err ( |e| format ! ( "Failed to run check-deposit-data command: {}" , e) ) ,
880
964
( "generate-bootnode-enr" , Some ( matches) ) => generate_bootnode_enr:: run :: < T > ( matches)
@@ -883,8 +967,16 @@ fn run<T: EthSpec>(
883
967
. map_err ( |e| format ! ( "Failed to run insecure-validators command: {}" , e) ) ,
884
968
( "indexed-attestations" , Some ( matches) ) => indexed_attestations:: run :: < T > ( matches)
885
969
. map_err ( |e| format ! ( "Failed to run indexed-attestations command: {}" , e) ) ,
886
- ( "block-root" , Some ( matches) ) => block_root:: run :: < T > ( env, matches)
887
- . map_err ( |e| format ! ( "Failed to run block-root command: {}" , e) ) ,
970
+ ( "block-root" , Some ( matches) ) => {
971
+ let network_config = get_network_config ( ) ?;
972
+ block_root:: run :: < T > ( env, network_config, matches)
973
+ . map_err ( |e| format ! ( "Failed to run block-root command: {}" , e) )
974
+ }
975
+ ( "state-root" , Some ( matches) ) => {
976
+ let network_config = get_network_config ( ) ?;
977
+ state_root:: run :: < T > ( env, network_config, matches)
978
+ . map_err ( |e| format ! ( "Failed to run state-root command: {}" , e) )
979
+ }
888
980
( other, _) => Err ( format ! ( "Unknown subcommand {}. See --help." , other) ) ,
889
981
}
890
982
}
0 commit comments