diff --git a/eigen_pod_proofs.go b/eigen_pod_proofs.go index 32281cf0..1b78e461 100644 --- a/eigen_pod_proofs.go +++ b/eigen_pod_proofs.go @@ -26,6 +26,9 @@ type EigenPodProofs struct { oracleStateCacheExpirySeconds int } +// NewEigenPodProofs creates a new EigenPodProofs instance. +// chainID is the chain ID of the chain that the EigenPodProofs instance will be used for. +// oracleStateCacheExpirySeconds is the expiry time for the oracle state cache in seconds. After this time caches of beacon state roots, validator trees and validator balances trees will be evicted. func NewEigenPodProofs(chainID uint64, oracleStateCacheExpirySeconds int) (*EigenPodProofs, error) { if chainID != 1 && chainID != 17000 { return nil, errors.New("chainID not supported") diff --git a/prove_validator.go b/prove_validator.go index d105fc17..47454a44 100644 --- a/prove_validator.go +++ b/prove_validator.go @@ -40,6 +40,10 @@ type VerifyCheckpointProofsCallParams struct { BalanceProofs []*BalanceProof `json:"balanceProofs"` } +// ProveValidatorContainers generates proofs for the validator containers. +// oracleBlockHeader is the block header of block whose state root will be looked up from the EIP-4788 precompile +// oracleBeaconState is the beacon state corresponding to the oracleBlockHeader +// validatorIndices is the list of validator indices for which the proofs are to be generated func (epp *EigenPodProofs) ProveValidatorContainers(oracleBlockHeader *phase0.BeaconBlockHeader, oracleBeaconState *spec.VersionedBeaconState, validatorIndices []uint64) (*VerifyValidatorFieldsCallParams, error) { oracleBeaconStateSlot, err := oracleBeaconState.Slot() if err != nil { @@ -77,7 +81,7 @@ func (epp *EigenPodProofs) ProveValidatorContainers(oracleBlockHeader *phase0.Be for i, validatorIndex := range validatorIndices { verifyValidatorFieldsCallParams.ValidatorIndices[i] = validatorIndex // prove the validator fields against the beacon state - verifyValidatorFieldsCallParams.ValidatorFieldsProofs[i], err = epp.ProveValidatorAgainstBeaconState(beaconStateTopLevelRoots, oracleBeaconStateSlot, oracleBeaconStateValidators, validatorIndex) + verifyValidatorFieldsCallParams.ValidatorFieldsProofs[i], err = epp.proveValidatorAgainstBeaconState(beaconStateTopLevelRoots, oracleBeaconStateSlot, oracleBeaconStateValidators, validatorIndex) if err != nil { return nil, err } @@ -88,42 +92,6 @@ func (epp *EigenPodProofs) ProveValidatorContainers(oracleBlockHeader *phase0.Be return verifyValidatorFieldsCallParams, nil } -func (epp *EigenPodProofs) ProveValidatorAgainstBeaconState(beaconStateTopLevelRoots *beacon.BeaconStateTopLevelRoots, oracleBeaconStateSlot phase0.Slot, oracleBeaconStateValidators []*phase0.Validator, validatorIndex uint64) (common.Proof, error) { - // prove the validator list against the beacon state - validatorListProof, err := beacon.ProveBeaconTopLevelRootAgainstBeaconState(beaconStateTopLevelRoots, beacon.VALIDATORS_INDEX) - if err != nil { - return nil, err - } - - // prove the validator root against the validator list root - validatorProof, err := epp.ProveValidatorAgainstValidatorList(oracleBeaconStateSlot, oracleBeaconStateValidators, validatorIndex) - if err != nil { - return nil, err - } - - proof := append(validatorProof, validatorListProof...) - - return proof, nil -} - -func (epp *EigenPodProofs) ProveValidatorAgainstValidatorList(slot phase0.Slot, validators []*phase0.Validator, validatorIndex uint64) (common.Proof, error) { - validatorTree, err := epp.ComputeValidatorTree(slot, validators) - if err != nil { - return nil, err - } - - proof, err := common.ComputeMerkleProofFromTree(validatorTree, validatorIndex, beacon.VALIDATOR_TREE_HEIGHT) - if err != nil { - return nil, err - } - //append the length of the validator array to the proof - //convert big endian to little endian - validatorListLenLE := BigToLittleEndian(big.NewInt(int64(len(validators)))) - - proof = append(proof, validatorListLenLE) - return proof, nil -} - func (epp *EigenPodProofs) ProveCheckpointProofs(oracleBlockHeader *phase0.BeaconBlockHeader, oracleBeaconState *spec.VersionedBeaconState, validatorIndices []uint64) (*VerifyCheckpointProofsCallParams, error) { oracleBeaconStateSlot, err := oracleBeaconState.Slot() if err != nil { @@ -166,7 +134,7 @@ func (epp *EigenPodProofs) ProveCheckpointProofs(oracleBlockHeader *phase0.Beaco verifyCheckpointProofsCallParams.BalanceProofs = make([]*BalanceProof, len(validatorIndices)) for i, validatorIndex := range validatorIndices { - balanceRoot, balanceProof, err := epp.ProveValidatorBalanceAgainstBeaconState(beaconStateTopLevelRoots, oracleBeaconStateSlot, oracleBeaconStateValidatorBalances, validatorIndex) + balanceRoot, balanceProof, err := epp.proveValidatorBalanceAgainstBeaconState(beaconStateTopLevelRoots, oracleBeaconStateSlot, oracleBeaconStateValidatorBalances, validatorIndex) if err != nil { return nil, err } @@ -185,9 +153,45 @@ func (epp *EigenPodProofs) ProveCheckpointProofs(oracleBlockHeader *phase0.Beaco return verifyCheckpointProofsCallParams, nil } -func (epp *EigenPodProofs) ProveValidatorBalanceAgainstBeaconState(beaconStateTopLevelRoots *beacon.BeaconStateTopLevelRoots, oracleBeaconStateSlot phase0.Slot, oracleBeaconStateValidatorBalances []phase0.Gwei, validatorIndex uint64) (phase0.Root, common.Proof, error) { +func (epp *EigenPodProofs) proveValidatorAgainstBeaconState(beaconStateTopLevelRoots *beacon.BeaconStateTopLevelRoots, oracleBeaconStateSlot phase0.Slot, oracleBeaconStateValidators []*phase0.Validator, validatorIndex uint64) (common.Proof, error) { + // prove the validator list against the beacon state + validatorListProof, err := beacon.ProveBeaconTopLevelRootAgainstBeaconState(beaconStateTopLevelRoots, beacon.VALIDATORS_INDEX) + if err != nil { + return nil, err + } + + // prove the validator root against the validator list root + validatorProof, err := epp.proveValidatorAgainstValidatorList(oracleBeaconStateSlot, oracleBeaconStateValidators, validatorIndex) + if err != nil { + return nil, err + } + + proof := append(validatorProof, validatorListProof...) + + return proof, nil +} + +func (epp *EigenPodProofs) proveValidatorAgainstValidatorList(slot phase0.Slot, validators []*phase0.Validator, validatorIndex uint64) (common.Proof, error) { + validatorTree, err := epp.ComputeValidatorTree(slot, validators) + if err != nil { + return nil, err + } + + proof, err := common.ComputeMerkleProofFromTree(validatorTree, validatorIndex, beacon.VALIDATOR_TREE_HEIGHT) + if err != nil { + return nil, err + } + //append the length of the validator array to the proof + //convert big endian to little endian + validatorListLenLE := BigToLittleEndian(big.NewInt(int64(len(validators)))) + + proof = append(proof, validatorListLenLE) + return proof, nil +} + +func (epp *EigenPodProofs) proveValidatorBalanceAgainstBeaconState(beaconStateTopLevelRoots *beacon.BeaconStateTopLevelRoots, oracleBeaconStateSlot phase0.Slot, oracleBeaconStateValidatorBalances []phase0.Gwei, validatorIndex uint64) (phase0.Root, common.Proof, error) { // prove the validator root against the validator list root - balanceRoot, balanceProof, err := epp.ProveValidatorBalanceAgainstValidatorBalancesList(oracleBeaconStateSlot, oracleBeaconStateValidatorBalances, validatorIndex) + balanceRoot, balanceProof, err := epp.proveValidatorBalanceAgainstValidatorBalancesList(oracleBeaconStateSlot, oracleBeaconStateValidatorBalances, validatorIndex) if err != nil { return phase0.Root{}, nil, err } @@ -195,7 +199,7 @@ func (epp *EigenPodProofs) ProveValidatorBalanceAgainstBeaconState(beaconStateTo return balanceRoot, balanceProof, nil } -func (epp *EigenPodProofs) ProveValidatorBalanceAgainstValidatorBalancesList(slot phase0.Slot, balances []phase0.Gwei, validatorIndex uint64) (phase0.Root, common.Proof, error) { +func (epp *EigenPodProofs) proveValidatorBalanceAgainstValidatorBalancesList(slot phase0.Slot, balances []phase0.Gwei, validatorIndex uint64) (phase0.Root, common.Proof, error) { validatorBalancesTree, err := epp.ComputeValidatorBalancesTree(slot, balances) if err != nil { return phase0.Root{}, nil, err