diff --git a/ProofGeneration b/ProofGeneration index 7641ffaf..99c50039 100755 Binary files a/ProofGeneration and b/ProofGeneration differ diff --git a/generate_balance_update_proof.go b/generate_balance_update_proof.go new file mode 100644 index 00000000..19233754 --- /dev/null +++ b/generate_balance_update_proof.go @@ -0,0 +1,70 @@ +package main + +import ( + "encoding/hex" + "encoding/json" + "os" + + "github.com/attestantio/go-eth2-client/spec/capella" + "github.com/attestantio/go-eth2-client/spec/phase0" + "github.com/rs/zerolog/log" +) + +func GenerateBalanceUpdateProof(oracleBlockHeaderFile string, stateFile string, validatorIndex uint64, chainID uint64, output string) { + + var state capella.BeaconState + var oracleBeaconBlockHeader phase0.BeaconBlockHeader + stateJSON, err := parseStateJSONFile(stateFile) + if err != nil { + log.Debug().AnErr("GenerateBalanceUpdateProof: error with JSON parsing", err) + } + ParseCapellaBeaconStateFromJSON(*stateJSON, &state) + + oracleBeaconBlockHeader, err = ExtractBlockHeader(oracleBlockHeaderFile) + if err != nil { + log.Debug().AnErr("Error with parsing header file", err) + } + + beaconStateRoot, err := state.HashTreeRoot() + + if err != nil { + log.Debug().AnErr("Error with HashTreeRoot of state", err) + } + + epp, err := NewEigenPodProofs(chainID, 1000) + if err != nil { + log.Debug().AnErr("Error creating EPP object", err) + } + + balanceRootList, err := GetBalanceRoots(state.Balances) + if err != nil { + log.Debug().AnErr("Error with GetBalanceRoots", err) + } + balanceRoot := balanceRootList[validatorIndex/4] + balanceProof, err := epp.ProveValidatorBalance(&oracleBeaconBlockHeader, &state, uint64(validatorIndex)) + if err != nil { + log.Debug().AnErr("Error with ProveValidatorBalance", err) + } + + stateRootProof, validatorFieldsProof, err := epp.ProveValidatorFields(&oracleBeaconBlockHeader, &state, uint64(validatorIndex)) + if err != nil { + log.Debug().AnErr("Error with ProveValidatorFields", err) + } + proofs := BalanceUpdateProofs{ + ValidatorIndex: uint64(validatorIndex), + BeaconStateRoot: "0x" + hex.EncodeToString(beaconStateRoot[:]), + BalanceRoot: "0x" + hex.EncodeToString(balanceRoot[:]), + ValidatorBalanceProof: ConvertBytesToStrings(balanceProof.BalanceUpdateProof.ValidatorBalanceProof), + StateRootAgainstLatestBlockHeaderProof: ConvertBytesToStrings(stateRootProof.StateRootProof), + WithdrawalCredentialProof: ConvertBytesToStrings(validatorFieldsProof), + ValidatorFields: GetValidatorFields(state.Validators[validatorIndex]), + } + + proofData, err := json.Marshal(proofs) + if err != nil { + log.Debug().AnErr("JSON marshal error: ", err) + } + + _ = os.WriteFile(output, proofData, 0644) + +} diff --git a/generate_validator_proof.go b/generate_validator_proof.go new file mode 100644 index 00000000..03d32c24 --- /dev/null +++ b/generate_validator_proof.go @@ -0,0 +1,61 @@ +package main + +import ( + "encoding/hex" + "encoding/json" + "os" + + "github.com/attestantio/go-eth2-client/spec/capella" + "github.com/attestantio/go-eth2-client/spec/phase0" + "github.com/rs/zerolog/log" +) + +func GenerateValidatorFieldsProof(oracleBlockHeaderFile string, stateFile string, validatorIndex uint64, chainID uint64, output string) { + + var state capella.BeaconState + var oracleBeaconBlockHeader phase0.BeaconBlockHeader + stateJSON, err := parseStateJSONFile(stateFile) + if err != nil { + log.Debug().Msg("GenerateValidatorFieldsProof: error with JSON parsing") + } + ParseCapellaBeaconStateFromJSON(*stateJSON, &state) + + oracleBeaconBlockHeader, err = ExtractBlockHeader(oracleBlockHeaderFile) + if err != nil { + log.Debug().AnErr("Error with parsing header file", err) + + } + + beaconStateRoot, err := state.HashTreeRoot() + + if err != nil { + log.Debug().AnErr("Error with HashTreeRoot of state", err) + } + + epp, err := NewEigenPodProofs(chainID, 1000) + if err != nil { + log.Debug().AnErr("Error creating EPP object", err) + + } + + stateRootProof, validatorFieldsProof, err := epp.ProveValidatorFields(&oracleBeaconBlockHeader, &state, uint64(validatorIndex)) + if err != nil { + log.Debug().AnErr("Error with ProveValidatorFields", err) + } + + proofs := WithdrawalCredentialProofs{ + StateRootAgainstLatestBlockHeaderProof: ConvertBytesToStrings(stateRootProof.StateRootProof), + BeaconStateRoot: "0x" + hex.EncodeToString(beaconStateRoot[:]), + ValidatorIndex: uint64(validatorIndex), + WithdrawalCredentialProof: ConvertBytesToStrings(validatorFieldsProof), + ValidatorFields: GetValidatorFields(state.Validators[validatorIndex]), + } + + proofData, err := json.Marshal(proofs) + if err != nil { + log.Debug().AnErr("JSON marshal error: ", err) + } + + _ = os.WriteFile(output, proofData, 0644) + +} diff --git a/generate_withdrawal_fields_proof.go b/generate_withdrawal_fields_proof.go new file mode 100644 index 00000000..7920c67f --- /dev/null +++ b/generate_withdrawal_fields_proof.go @@ -0,0 +1,137 @@ +package main + +import ( + "encoding/hex" + "encoding/json" + "os" + + "github.com/attestantio/go-eth2-client/spec/capella" + "github.com/attestantio/go-eth2-client/spec/phase0" + ssz "github.com/ferranbt/fastssz" + "github.com/rs/zerolog/log" +) + +func GenerateWithdrawalFieldsProof( + oracleBlockHeaderFile, + stateFile, + historicalSummaryStateFile, + blockHeaderFile, + blockBodyFile string, + validatorIndex, + withdrawalIndex, + historicalSummariesIndex, + blockHeaderIndex, + chainID uint64, + outputFile string, +) { + + //this is the oracle provided state + var oracleBeaconBlockHeader phase0.BeaconBlockHeader + //this is the state with the withdrawal in it + var state capella.BeaconState + var historicalSummaryState capella.BeaconState + var withdrawalBlockHeader phase0.BeaconBlockHeader + var withdrawalBlock capella.BeaconBlock + + oracleBeaconBlockHeader, err := ExtractBlockHeader(oracleBlockHeaderFile) + if err != nil { + log.Debug().AnErr("Error with parsing header file", err) + } + + stateJSON, err := parseStateJSONFile(stateFile) + if err != nil { + log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with JSON parsing state file", err) + } + ParseCapellaBeaconStateFromJSON(*stateJSON, &state) + + historicalSummaryJSON, err := parseStateJSONFile(historicalSummaryStateFile) + if err != nil { + log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with JSON parsing historical summary state file", err) + } + ParseCapellaBeaconStateFromJSON(*historicalSummaryJSON, &historicalSummaryState) + + withdrawalBlockHeader, err = ExtractBlockHeader(blockHeaderFile) + if err != nil { + log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with parsing header file", err) + } + + withdrawalBlock, err = ExtractBlock(blockBodyFile) + if err != nil { + log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with parsing body file", err) + } + + hh := ssz.NewHasher() + + beaconBlockHeaderToVerifyIndex := blockHeaderIndex + + // validatorIndex := phase0.ValidatorIndex(index) + beaconStateRoot, err := state.HashTreeRoot() + if err != nil { + log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with HashTreeRoot of state", err) + } + + slot := withdrawalBlockHeader.Slot + hh.PutUint64(uint64(slot)) + slotRoot := ConvertTo32ByteArray(hh.Hash()) + + timestamp := withdrawalBlock.Body.ExecutionPayload.Timestamp + hh.PutUint64(uint64(timestamp)) + timestampRoot := ConvertTo32ByteArray(hh.Hash()) + + blockHeaderRoot, err := withdrawalBlockHeader.HashTreeRoot() + if err != nil { + log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with HashTreeRoot of blockHeader", err) + } + executionPayloadRoot, err := withdrawalBlock.Body.ExecutionPayload.HashTreeRoot() + if err != nil { + log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with HashTreeRoot of executionPayload", err) + } + + epp, err := NewEigenPodProofs(chainID, 1000) + if err != nil { + log.Debug().AnErr("GenerateWithdrawalFieldsProof: error creating EPP object", err) + } + oracleBeaconStateTopLevelRoots, err := epp.ComputeBeaconStateTopLevelRoots(&state) + if err != nil { + log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with ComputeBeaconStateTopLevelRoots", err) + } + withdrawalProof, err := epp.ProveWithdrawal(&oracleBeaconBlockHeader, &state, oracleBeaconStateTopLevelRoots, historicalSummaryState.BlockRoots, &withdrawalBlock, uint64(validatorIndex), FIRST_CAPELLA_SLOT_GOERLI) + if err != nil { + log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with ProveWithdrawal", err) + } + stateRootProof, err := ProveStateRootAgainstBlockHeader(&oracleBeaconBlockHeader) + if err != nil { + log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with ProveStateRootAgainstBlockHeader", err) + } + validatorProof, err := epp.ProveValidatorAgainstBeaconState(&state, oracleBeaconStateTopLevelRoots, uint64(validatorIndex)) + if err != nil { + log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with ProveValidatorAgainstBeaconState", err) + } + proofs := WithdrawalProofs{ + StateRootAgainstLatestBlockHeaderProof: ConvertBytesToStrings(stateRootProof), + BeaconStateRoot: "0x" + hex.EncodeToString(beaconStateRoot[:]), + WithdrawalProof: ConvertBytesToStrings(withdrawalProof.WithdrawalProof), + SlotProof: ConvertBytesToStrings(withdrawalProof.SlotProof), + ExecutionPayloadProof: ConvertBytesToStrings(withdrawalProof.ExecutionPayloadProof), + TimestampProof: ConvertBytesToStrings(withdrawalProof.TimestampProof), + HistoricalSummaryProof: ConvertBytesToStrings(withdrawalProof.HistoricalSummaryBlockRootProof), + BlockHeaderRootIndex: beaconBlockHeaderToVerifyIndex, + HistoricalSummaryIndex: uint64(historicalSummariesIndex), + WithdrawalIndex: withdrawalIndex, + BlockHeaderRoot: "0x" + hex.EncodeToString(blockHeaderRoot[:]), + SlotRoot: "0x" + hex.EncodeToString(slotRoot[:]), + TimestampRoot: "0x" + hex.EncodeToString(timestampRoot[:]), + ExecutionPayloadRoot: "0x" + hex.EncodeToString(executionPayloadRoot[:]), + ValidatorProof: ConvertBytesToStrings(validatorProof), + ValidatorFields: GetValidatorFields(state.Validators[validatorIndex]), + WithdrawalFields: GetWithdrawalFields(withdrawalBlock.Body.ExecutionPayload.Withdrawals[withdrawalIndex]), + } + + proofData, err := json.Marshal(proofs) + if err != nil { + log.Debug().AnErr("JSON marshal error: ", err) + } + + _ = os.WriteFile(outputFile, proofData, 0644) + +} diff --git a/main.go b/main.go index 9ed0bb52..dc33655f 100644 --- a/main.go +++ b/main.go @@ -1,14 +1,8 @@ package main import ( - "encoding/hex" - "encoding/json" "flag" - "os" - "github.com/attestantio/go-eth2-client/spec/capella" - "github.com/attestantio/go-eth2-client/spec/phase0" - ssz "github.com/ferranbt/fastssz" "github.com/rs/zerolog" "github.com/rs/zerolog/log" ) @@ -60,237 +54,3 @@ func main() { log.Debug().Str("Unknown command:", *command) } } - -func GenerateValidatorFieldsProof(oracleBlockHeaderFile string, stateFile string, validatorIndex uint64, chainID uint64, output string) { - - var state capella.BeaconState - var oracleBeaconBlockHeader phase0.BeaconBlockHeader - stateJSON, err := parseStateJSONFile(stateFile) - if err != nil { - log.Debug().Msg("GenerateValidatorFieldsProof: error with JSON parsing") - } - ParseCapellaBeaconStateFromJSON(*stateJSON, &state) - - oracleBeaconBlockHeader, err = ExtractBlockHeader(oracleBlockHeaderFile) - if err != nil { - log.Debug().AnErr("Error with parsing header file", err) - - } - - beaconStateRoot, err := state.HashTreeRoot() - - if err != nil { - log.Debug().AnErr("Error with HashTreeRoot of state", err) - } - - epp, err := NewEigenPodProofs(chainID, 1000) - if err != nil { - log.Debug().AnErr("Error creating EPP object", err) - - } - - stateRootProof, validatorFieldsProof, err := epp.ProveValidatorFields(&oracleBeaconBlockHeader, &state, uint64(validatorIndex)) - if err != nil { - log.Debug().AnErr("Error with ProveValidatorFields", err) - } - - proofs := WithdrawalCredentialProofs{ - StateRootAgainstLatestBlockHeaderProof: ConvertBytesToStrings(stateRootProof.StateRootProof), - BeaconStateRoot: "0x" + hex.EncodeToString(beaconStateRoot[:]), - ValidatorIndex: uint64(validatorIndex), - WithdrawalCredentialProof: ConvertBytesToStrings(validatorFieldsProof), - ValidatorFields: GetValidatorFields(state.Validators[validatorIndex]), - } - - proofData, err := json.Marshal(proofs) - if err != nil { - log.Debug().AnErr("JSON marshal error: ", err) - } - - _ = os.WriteFile(output, proofData, 0644) - -} - -func GenerateBalanceUpdateProof(oracleBlockHeaderFile string, stateFile string, validatorIndex uint64, chainID uint64, output string) { - - var state capella.BeaconState - var oracleBeaconBlockHeader phase0.BeaconBlockHeader - stateJSON, err := parseStateJSONFile(stateFile) - if err != nil { - log.Debug().AnErr("GenerateBalanceUpdateProof: error with JSON parsing", err) - } - ParseCapellaBeaconStateFromJSON(*stateJSON, &state) - - oracleBeaconBlockHeader, err = ExtractBlockHeader(oracleBlockHeaderFile) - if err != nil { - log.Debug().AnErr("Error with parsing header file", err) - } - - beaconStateRoot, err := state.HashTreeRoot() - - if err != nil { - log.Debug().AnErr("Error with HashTreeRoot of state", err) - } - - epp, err := NewEigenPodProofs(chainID, 1000) - if err != nil { - log.Debug().AnErr("Error creating EPP object", err) - } - - balanceRootList, err := GetBalanceRoots(state.Balances) - if err != nil { - log.Debug().AnErr("Error with GetBalanceRoots", err) - } - balanceRoot := balanceRootList[validatorIndex/4] - balanceProof, err := epp.ProveValidatorBalance(&oracleBeaconBlockHeader, &state, uint64(validatorIndex)) - if err != nil { - log.Debug().AnErr("Error with ProveValidatorBalance", err) - } - - stateRootProof, validatorFieldsProof, err := epp.ProveValidatorFields(&oracleBeaconBlockHeader, &state, uint64(validatorIndex)) - if err != nil { - log.Debug().AnErr("Error with ProveValidatorFields", err) - } - proofs := BalanceUpdateProofs{ - ValidatorIndex: uint64(validatorIndex), - BeaconStateRoot: "0x" + hex.EncodeToString(beaconStateRoot[:]), - BalanceRoot: "0x" + hex.EncodeToString(balanceRoot[:]), - ValidatorBalanceProof: ConvertBytesToStrings(balanceProof.BalanceUpdateProof.ValidatorBalanceProof), - StateRootAgainstLatestBlockHeaderProof: ConvertBytesToStrings(stateRootProof.StateRootProof), - WithdrawalCredentialProof: ConvertBytesToStrings(validatorFieldsProof), - ValidatorFields: GetValidatorFields(state.Validators[validatorIndex]), - } - - proofData, err := json.Marshal(proofs) - if err != nil { - log.Debug().AnErr("JSON marshal error: ", err) - } - - _ = os.WriteFile(output, proofData, 0644) - -} - -func GenerateWithdrawalFieldsProof( - oracleBlockHeaderFile, - stateFile, - historicalSummaryStateFile, - blockHeaderFile, - blockBodyFile string, - validatorIndex, - withdrawalIndex, - historicalSummariesIndex, - blockHeaderIndex, - chainID uint64, - outputFile string, -) { - - //this is the oracle provided state - var oracleBeaconBlockHeader phase0.BeaconBlockHeader - //this is the state with the withdrawal in it - var state capella.BeaconState - var historicalSummaryState capella.BeaconState - var withdrawalBlockHeader phase0.BeaconBlockHeader - var withdrawalBlock capella.BeaconBlock - - oracleBeaconBlockHeader, err := ExtractBlockHeader(oracleBlockHeaderFile) - if err != nil { - log.Debug().AnErr("Error with parsing header file", err) - } - - stateJSON, err := parseStateJSONFile(stateFile) - if err != nil { - log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with JSON parsing state file", err) - } - ParseCapellaBeaconStateFromJSON(*stateJSON, &state) - - historicalSummaryJSON, err := parseStateJSONFile(historicalSummaryStateFile) - if err != nil { - log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with JSON parsing historical summary state file", err) - } - ParseCapellaBeaconStateFromJSON(*historicalSummaryJSON, &historicalSummaryState) - - withdrawalBlockHeader, err = ExtractBlockHeader(blockHeaderFile) - if err != nil { - log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with parsing header file", err) - } - - withdrawalBlock, err = ExtractBlock(blockBodyFile) - if err != nil { - log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with parsing body file", err) - } - - hh := ssz.NewHasher() - - beaconBlockHeaderToVerifyIndex := blockHeaderIndex - - // validatorIndex := phase0.ValidatorIndex(index) - beaconStateRoot, err := state.HashTreeRoot() - if err != nil { - log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with HashTreeRoot of state", err) - } - - slot := withdrawalBlockHeader.Slot - hh.PutUint64(uint64(slot)) - slotRoot := ConvertTo32ByteArray(hh.Hash()) - - timestamp := withdrawalBlock.Body.ExecutionPayload.Timestamp - hh.PutUint64(uint64(timestamp)) - timestampRoot := ConvertTo32ByteArray(hh.Hash()) - - blockHeaderRoot, err := withdrawalBlockHeader.HashTreeRoot() - if err != nil { - log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with HashTreeRoot of blockHeader", err) - } - executionPayloadRoot, err := withdrawalBlock.Body.ExecutionPayload.HashTreeRoot() - if err != nil { - log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with HashTreeRoot of executionPayload", err) - } - - epp, err := NewEigenPodProofs(chainID, 1000) - if err != nil { - log.Debug().AnErr("GenerateWithdrawalFieldsProof: error creating EPP object", err) - } - oracleBeaconStateTopLevelRoots, err := epp.ComputeBeaconStateTopLevelRoots(&state) - if err != nil { - log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with ComputeBeaconStateTopLevelRoots", err) - } - withdrawalProof, err := epp.ProveWithdrawal(&oracleBeaconBlockHeader, &state, oracleBeaconStateTopLevelRoots, historicalSummaryState.BlockRoots, &withdrawalBlock, uint64(validatorIndex), FIRST_CAPELLA_SLOT_GOERLI) - if err != nil { - log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with ProveWithdrawal", err) - } - stateRootProof, err := ProveStateRootAgainstBlockHeader(&oracleBeaconBlockHeader) - if err != nil { - log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with ProveStateRootAgainstBlockHeader", err) - } - validatorProof, err := epp.ProveValidatorAgainstBeaconState(&state, oracleBeaconStateTopLevelRoots, uint64(validatorIndex)) - if err != nil { - log.Debug().AnErr("GenerateWithdrawalFieldsProof: error with ProveValidatorAgainstBeaconState", err) - } - proofs := WithdrawalProofs{ - StateRootAgainstLatestBlockHeaderProof: ConvertBytesToStrings(stateRootProof), - BeaconStateRoot: "0x" + hex.EncodeToString(beaconStateRoot[:]), - WithdrawalProof: ConvertBytesToStrings(withdrawalProof.WithdrawalProof), - SlotProof: ConvertBytesToStrings(withdrawalProof.SlotProof), - ExecutionPayloadProof: ConvertBytesToStrings(withdrawalProof.ExecutionPayloadProof), - TimestampProof: ConvertBytesToStrings(withdrawalProof.TimestampProof), - HistoricalSummaryProof: ConvertBytesToStrings(withdrawalProof.HistoricalSummaryBlockRootProof), - BlockHeaderRootIndex: beaconBlockHeaderToVerifyIndex, - HistoricalSummaryIndex: uint64(historicalSummariesIndex), - WithdrawalIndex: withdrawalIndex, - BlockHeaderRoot: "0x" + hex.EncodeToString(blockHeaderRoot[:]), - SlotRoot: "0x" + hex.EncodeToString(slotRoot[:]), - TimestampRoot: "0x" + hex.EncodeToString(timestampRoot[:]), - ExecutionPayloadRoot: "0x" + hex.EncodeToString(executionPayloadRoot[:]), - ValidatorProof: ConvertBytesToStrings(validatorProof), - ValidatorFields: GetValidatorFields(state.Validators[validatorIndex]), - WithdrawalFields: GetWithdrawalFields(withdrawalBlock.Body.ExecutionPayload.Withdrawals[withdrawalIndex]), - } - - proofData, err := json.Marshal(proofs) - if err != nil { - log.Debug().AnErr("JSON marshal error: ", err) - } - - _ = os.WriteFile(outputFile, proofData, 0644) - -}