github.com/prysmaticlabs/prysm@v1.4.4/tools/benchmark-files-gen/main.go (about) 1 package main 2 3 import ( 4 "context" 5 "flag" 6 "io/ioutil" 7 "log" 8 "os" 9 "path" 10 11 "github.com/pkg/errors" 12 types "github.com/prysmaticlabs/eth2-types" 13 "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers" 14 "github.com/prysmaticlabs/prysm/beacon-chain/core/state" 15 iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface" 16 "github.com/prysmaticlabs/prysm/beacon-chain/state/v1" 17 pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1" 18 ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1" 19 "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper" 20 "github.com/prysmaticlabs/prysm/shared/benchutil" 21 "github.com/prysmaticlabs/prysm/shared/fileutil" 22 "github.com/prysmaticlabs/prysm/shared/interop" 23 "github.com/prysmaticlabs/prysm/shared/params" 24 "github.com/prysmaticlabs/prysm/shared/testutil" 25 ) 26 27 var ( 28 outputDir = flag.String("output-dir", "", "Directory to write SSZ files to") 29 overwrite = flag.Bool("overwrite", false, "If SSZ files exist in the output directory, they will be overwritten") 30 ) 31 32 func main() { 33 flag.Parse() 34 if *outputDir == "" { 35 log.Fatal("Please specify --output-dir to write SSZ files to") 36 } 37 38 if !*overwrite { 39 if _, err := os.Stat(path.Join(*outputDir, benchutil.BState1EpochFileName)); err == nil { 40 log.Fatal("The file exists. Use a different file name or the --overwrite flag") 41 } 42 if _, err := os.Stat(path.Join(*outputDir, benchutil.BState2EpochFileName)); err == nil { 43 log.Fatal("The file exists. Use a different file name or the --overwrite flag") 44 } 45 if _, err := os.Stat(path.Join(*outputDir, benchutil.FullBlockFileName)); err == nil { 46 log.Fatal("The file exists. Use a different file name or the --overwrite flag") 47 } 48 } 49 50 if err := fileutil.MkdirAll(*outputDir); err != nil { 51 log.Fatal(err) 52 } 53 54 log.Printf("Output dir is: %s", *outputDir) 55 log.Println("Generating genesis state") 56 // Generating this for the 2 following states. 57 if err := generateGenesisBeaconState(); err != nil { 58 log.Fatalf("Could not generate genesis state: %v", err) 59 } 60 log.Println("Generating full block and state after 1 skipped epoch") 61 if err := generateMarshalledFullStateAndBlock(); err != nil { 62 log.Fatalf("Could not generate full state and block: %v", err) 63 } 64 log.Println("Generating state after 2 fully attested epochs") 65 if err := generate2FullEpochState(); err != nil { 66 log.Fatalf("Could not generate 2 full epoch state: %v", err) 67 } 68 // Removing the genesis state SSZ since its 10MB large and no longer needed. 69 if err := os.Remove(path.Join(*outputDir, benchutil.GenesisFileName)); err != nil { 70 log.Fatal(err) 71 } 72 } 73 74 func generateGenesisBeaconState() error { 75 genesisState, _, err := interop.GenerateGenesisState(context.Background(), 0, benchutil.ValidatorCount) 76 if err != nil { 77 return err 78 } 79 beaconBytes, err := genesisState.MarshalSSZ() 80 if err != nil { 81 return err 82 } 83 return fileutil.WriteFile(path.Join(*outputDir, benchutil.GenesisFileName), beaconBytes) 84 } 85 86 func generateMarshalledFullStateAndBlock() error { 87 benchutil.SetBenchmarkConfig() 88 beaconState, err := genesisBeaconState() 89 if err != nil { 90 return err 91 } 92 93 privs, _, err := interop.DeterministicallyGenerateKeys(0, benchutil.ValidatorCount) 94 if err != nil { 95 return err 96 } 97 98 conf := &testutil.BlockGenConfig{} 99 slotsPerEpoch := params.BeaconConfig().SlotsPerEpoch 100 // Small offset for the beacon state so we dont process a block on an epoch. 101 slotOffset := types.Slot(2) 102 block, err := testutil.GenerateFullBlock(beaconState, privs, conf, slotsPerEpoch+slotOffset) 103 if err != nil { 104 return err 105 } 106 beaconState, err = state.ExecuteStateTransition(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(block)) 107 if err != nil { 108 return err 109 } 110 111 attConfig := &testutil.BlockGenConfig{ 112 NumAttestations: benchutil.AttestationsPerEpoch / uint64(slotsPerEpoch), 113 } 114 115 var atts []*ethpb.Attestation 116 for i := slotOffset + 1; i < slotsPerEpoch+slotOffset; i++ { 117 attsForSlot, err := testutil.GenerateAttestations(beaconState, privs, attConfig.NumAttestations, i, false) 118 if err != nil { 119 return err 120 } 121 atts = append(atts, attsForSlot...) 122 } 123 124 block, err = testutil.GenerateFullBlock(beaconState, privs, attConfig, beaconState.Slot()) 125 if err != nil { 126 return errors.Wrap(err, "could not generate full block") 127 } 128 block.Block.Body.Attestations = append(atts, block.Block.Body.Attestations...) 129 130 s, err := state.CalculateStateRoot(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(block)) 131 if err != nil { 132 return errors.Wrap(err, "could not calculate state root") 133 } 134 block.Block.StateRoot = s[:] 135 // Temporarily incrementing the beacon state slot here since BeaconProposerIndex is a 136 // function deterministic on beacon state slot. 137 if err := beaconState.SetSlot(beaconState.Slot() + 1); err != nil { 138 return err 139 } 140 proposerIdx, err := helpers.BeaconProposerIndex(beaconState) 141 if err != nil { 142 return err 143 } 144 block.Signature, err = helpers.ComputeDomainAndSign(beaconState, helpers.CurrentEpoch(beaconState), block.Block, params.BeaconConfig().DomainBeaconProposer, privs[proposerIdx]) 145 if err != nil { 146 return err 147 } 148 if err := beaconState.SetSlot(beaconState.Slot() - 1); err != nil { 149 return err 150 } 151 152 beaconBytes, err := beaconState.MarshalSSZ() 153 if err != nil { 154 return err 155 } 156 if err := fileutil.WriteFile(path.Join(*outputDir, benchutil.BState1EpochFileName), beaconBytes); err != nil { 157 return err 158 } 159 160 // Running a single state transition to make sure the generated files aren't broken. 161 _, err = state.ExecuteStateTransition(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(block)) 162 if err != nil { 163 return err 164 } 165 166 blockBytes, err := block.MarshalSSZ() 167 if err != nil { 168 return err 169 } 170 171 return fileutil.WriteFile(path.Join(*outputDir, benchutil.FullBlockFileName), blockBytes) 172 } 173 174 func generate2FullEpochState() error { 175 benchutil.SetBenchmarkConfig() 176 beaconState, err := genesisBeaconState() 177 if err != nil { 178 return err 179 } 180 181 privs, _, err := interop.DeterministicallyGenerateKeys(0, benchutil.ValidatorCount) 182 if err != nil { 183 return err 184 } 185 186 attConfig := &testutil.BlockGenConfig{ 187 NumAttestations: benchutil.AttestationsPerEpoch / uint64(params.BeaconConfig().SlotsPerEpoch), 188 } 189 190 for i := types.Slot(0); i < params.BeaconConfig().SlotsPerEpoch*2-1; i++ { 191 block, err := testutil.GenerateFullBlock(beaconState, privs, attConfig, beaconState.Slot()) 192 if err != nil { 193 return err 194 } 195 beaconState, err = state.ExecuteStateTransition(context.Background(), beaconState, wrapper.WrappedPhase0SignedBeaconBlock(block)) 196 if err != nil { 197 return err 198 } 199 } 200 201 beaconBytes, err := beaconState.MarshalSSZ() 202 if err != nil { 203 return err 204 } 205 206 return fileutil.WriteFile(path.Join(*outputDir, benchutil.BState2EpochFileName), beaconBytes) 207 } 208 209 func genesisBeaconState() (iface.BeaconState, error) { 210 beaconBytes, err := ioutil.ReadFile(path.Join(*outputDir, benchutil.GenesisFileName)) 211 if err != nil { 212 return nil, errors.Wrap(err, "cannot read genesis state file") 213 } 214 genesisState := &pb.BeaconState{} 215 if err := genesisState.UnmarshalSSZ(beaconBytes); err != nil { 216 return nil, errors.Wrap(err, "cannot unmarshal genesis state file") 217 } 218 return v1.InitializeFromProtoUnsafe(genesisState) 219 }