diff --git a/fluffy/network/history/experimental/beacon_chain_block_proof.nim b/fluffy/network/history/experimental/beacon_chain_block_proof.nim index 7d4c6c1da..7cef1ee6a 100644 --- a/fluffy/network/history/experimental/beacon_chain_block_proof.nim +++ b/fluffy/network/history/experimental/beacon_chain_block_proof.nim @@ -87,12 +87,12 @@ type BeaconChainBlockProof* = object # Total size (8 + 1 + 3 + 1 + 14) * 32 bytes + 4 bytes = 868 bytes - beaconBlockBodyProof: BeaconBlockBodyProof - beaconBlockBodyRoot: Digest - beaconBlockHeaderProof: BeaconBlockHeaderProof - beaconBlockHeaderRoot: Digest - historicalRootsProof: HistoricalRootsProof - slot: Slot + beaconBlockBodyProof*: BeaconBlockBodyProof + beaconBlockBodyRoot*: Digest + beaconBlockHeaderProof*: BeaconBlockHeaderProof + beaconBlockHeaderRoot*: Digest + historicalRootsProof*: HistoricalRootsProof + slot*: Slot func getHistoricalRootsIndex*(slot: Slot): uint64 = slot div SLOTS_PER_HISTORICAL_ROOT @@ -109,7 +109,7 @@ func getBlockRootsIndex*(blockHeader: BeaconBlockHeader): uint64 = # Builds proof to be able to verify that the EL block hash is part of # BeaconBlockBody for given root. func buildProof*( - blockBody: bellatrix.BeaconBlockBody + blockBody: bellatrix.TrustedBeaconBlockBody | bellatrix.BeaconBlockBody ): Result[BeaconBlockBodyProof, string] = # 16 as there are 10 fields # 9 as index (pos) of field = 9 @@ -152,7 +152,7 @@ func buildProof*( func buildProof*( batch: HistoricalBatch, blockHeader: BeaconBlockHeader, - blockBody: bellatrix.BeaconBlockBody, + blockBody: bellatrix.TrustedBeaconBlockBody | bellatrix.BeaconBlockBody, ): Result[BeaconChainBlockProof, string] = let blockRootIndex = getBlockRootsIndex(blockHeader) diff --git a/fluffy/tools/eth_data_exporter.nim b/fluffy/tools/eth_data_exporter.nim index 8f2b9f089..64a2fdd11 100644 --- a/fluffy/tools/eth_data_exporter.nim +++ b/fluffy/tools/eth_data_exporter.nim @@ -692,3 +692,7 @@ when isMainModule: waitFor exportHistoricalRoots( config.restUrl, string config.dataDir, cfg, forkDigests ) + of BeaconCmd.exportBlockProofBellatrix: + cmdExportBlockProofBellatrix( + string config.dataDir, string config.eraDir, config.slotNumber + ) diff --git a/fluffy/tools/eth_data_exporter/cl_data_exporter.nim b/fluffy/tools/eth_data_exporter/cl_data_exporter.nim index 23136ebda..01fe1bd21 100644 --- a/fluffy/tools/eth_data_exporter/cl_data_exporter.nim +++ b/fluffy/tools/eth_data_exporter/cl_data_exporter.nim @@ -13,12 +13,19 @@ import chronos, stew/[byteutils, io2], eth/async_utils, + beacon_chain/era_db, + beacon_chain/spec/forks, beacon_chain/networking/network_metadata, beacon_chain/spec/eth2_apis/rest_beacon_client, beacon_chain/beacon_clock, ../../network/beacon/beacon_content, + ../../network/beacon/beacon_init_loader, + ../../network/history/experimental/beacon_chain_block_proof, + ../../network_metadata, ./exporter_common +from beacon_chain/el/el_manager import toBeaconBlockHeader + export beacon_clock const @@ -296,3 +303,48 @@ proc exportHistoricalRoots*( quit 1 else: notice "Succesfully wrote historical_roots to file", file + +proc cmdExportBlockProofBellatrix*( + dataDir: string, eraDir: string, slotNumber: uint64 +) = + let + networkData = loadNetworkData("mainnet") + db = + EraDB.new(networkData.metadata.cfg, eraDir, networkData.genesis_validators_root) + historical_roots = loadHistoricalRoots().asSeq() + slot = Slot(slotNumber) + era = era(slot) + + # Note: Provide just empty historical_summaries here as this is only + # supposed to generate proofs for Bellatrix for now. + # For later proofs, it will be more difficult to use this call as we need + # to provide the (changing) historical summaries. Probably want to directly + # grab the right era file through different calls then. + var state: ForkedHashedBeaconState + db.getState(historical_roots, [], start_slot(era + 1), state).isOkOr: + error "Failed to load state", error = error + quit QuitFailure + + let batch = HistoricalBatch( + block_roots: getStateField(state, block_roots).data, + state_roots: getStateField(state, state_roots).data, + ) + + let beaconBlock = db.getBlock( + historical_roots, [], slot, Opt.none(Eth2Digest), bellatrix.TrustedSignedBeaconBlock + ).valueOr: + error "Failed to load Bellatrix block", slot + quit QuitFailure + + let beaconBlockHeader = beaconBlock.toBeaconBlockHeader() + let blockProof = buildProof(batch, beaconBlockHeader, beaconBlock.message.body).valueOr: + error "Failed to build proof for Bellatrix block", slot, error + quit QuitFailure + + let file = dataDir / "block_proof_" & $slot & ".ssz" + let res = io2.writeFile(file, SSZ.encode(blockProof)) + if res.isErr(): + error "Failed writing block proof to file", file, error = ioErrorMsg(res.error) + quit 1 + else: + notice "Succesfully wrote block proof to file", file diff --git a/fluffy/tools/eth_data_exporter/exporter_conf.nim b/fluffy/tools/eth_data_exporter/exporter_conf.nim index dfd7da1fb..1e0ba3dc3 100644 --- a/fluffy/tools/eth_data_exporter/exporter_conf.nim +++ b/fluffy/tools/eth_data_exporter/exporter_conf.nim @@ -70,6 +70,7 @@ type exportLCFinalityUpdate = "Export Light Client Finality Update" exportLCOptimisticUpdate = "Export Light Client Optimistic Update" exportHistoricalRoots = "Export historical roots from the beacon state (SSZ format)" + exportBlockProofBellatrix = "Export Bellatrix EL block proof from era files" ExporterConf* = object logLevel* {. @@ -210,6 +211,11 @@ type discard of exportHistoricalRoots: discard + of exportBlockProofBellatrix: + slotNumber* {. + desc: "The slot for which to export the block proof", name: "slot" + .}: uint64 + eraDir* {.desc: "Directory containing era files", name: "era-dir".}: InputDir proc parseCmdArg*(T: type Web3Url, p: string): T {.raises: [ValueError].} = let