Update DepositRoot to Eth1Data (#1403)

* update proto fileds

* Start writing ProcessETH1Data function

* More progress on tests

* Continue more work on tests

* Fix almost all the tests

* Fix all tests

* Fix everything

* Fix after rebase

* Fix for suggestions and fix per-epoch operation

* Remove method usage

* Fix build

* Fix suggestions

* Fix merge issues and suggestions

* Fix rebase issues

* Remove the error from ProcessETH1Data

* WIP write test

* Update test to reach crosslinks

* Revert "Update test to reach crosslinks"

This reverts commit 5ff9177f96c12c98c54eafffcfb385bd966b0888.

* Revert "WIP write test"

This reverts commit f7e7ed715c4af6b7e3c95643f7ebf85830caf638.
This commit is contained in:
Ivan Martinez 2019-02-02 16:24:42 -05:00 committed by Preston Van Loon
parent d06f5ac163
commit 5b209a2b18
19 changed files with 1106 additions and 676 deletions

View File

@ -255,9 +255,12 @@ func TestRunningChainServiceFaultyPOWChain(t *testing.T) {
}
block := &pb.BeaconBlock{
Slot: 2,
ParentRootHash32: parentHash[:],
DepositRootHash32: []byte("a"),
Slot: 2,
ParentRootHash32: parentHash[:],
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte("a"),
BlockHash32: []byte("b"),
},
}
exitRoutine := make(chan bool)
@ -347,10 +350,13 @@ func TestRunningChainService(t *testing.T) {
attestationSlot := uint64(0)
block := &pb.BeaconBlock{
Slot: currentSlot + 1,
StateRootHash32: stateRoot[:],
ParentRootHash32: parentHash[:],
DepositRootHash32: []byte("a"),
Slot: currentSlot + 1,
StateRootHash32: stateRoot[:],
ParentRootHash32: parentHash[:],
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte("a"),
BlockHash32: []byte("b"),
},
Body: &pb.BeaconBlockBody{
Attestations: []*pb.Attestation{{
ParticipationBitfield: []byte{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@ -402,7 +408,7 @@ func TestDoesPOWBlockExist(t *testing.T) {
}
// Using a faulty client should throw error.
powHash := bytesutil.ToBytes32(beaconState.LatestDepositRootHash32)
powHash := bytesutil.ToBytes32(beaconState.LatestEth1Data.DepositRootHash32)
exists := chainService.doesPoWBlockExist(powHash)
if exists {
t.Error("Block corresponding to nil powchain reference should not exist")
@ -465,10 +471,13 @@ func TestUpdateHead(t *testing.T) {
enc, _ := proto.Marshal(tt.state)
stateRoot := hashutil.Hash(enc)
block := &pb.BeaconBlock{
Slot: tt.blockSlot,
StateRootHash32: stateRoot[:],
ParentRootHash32: genesisHash[:],
DepositRootHash32: []byte("a"),
Slot: tt.blockSlot,
StateRootHash32: stateRoot[:],
ParentRootHash32: genesisHash[:],
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte("a"),
BlockHash32: []byte("b"),
},
}
if err := chainService.beaconDB.SaveBlock(block); err != nil {
t.Fatal(err)
@ -527,18 +536,23 @@ func TestIsBlockReadyForProcessing(t *testing.T) {
t.Fatal("block processing succeeded despite block slot being invalid")
}
h := bytesutil.ToBytes32([]byte("a"))
beaconState.LatestDepositRootHash32 = h[:]
beaconState.LatestEth1Data = &pb.Eth1Data{
DepositRootHash32: []byte{2},
BlockHash32: []byte{3},
}
beaconState.Slot = 0
currentSlot := uint64(1)
attestationSlot := uint64(0)
block3 := &pb.BeaconBlock{
Slot: currentSlot,
StateRootHash32: stateRoot[:],
ParentRootHash32: parentHash[:],
DepositRootHash32: []byte("a"),
Slot: currentSlot,
StateRootHash32: stateRoot[:],
ParentRootHash32: parentHash[:],
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte("a"),
BlockHash32: []byte("b"),
},
Body: &pb.BeaconBlockBody{
Attestations: []*pb.Attestation{{
ParticipationBitfield: []byte{128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

View File

@ -37,6 +37,10 @@ func generateSimulatedBlock(
RandaoRevealHash32: randaoReveal[:],
ParentRootHash32: prevBlockRoot[:],
StateRootHash32: stateRoot[:],
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{1},
BlockHash32: []byte{2},
},
Body: &pb.BeaconBlockBody{
ProposerSlashings: []*pb.ProposerSlashing{},
AttesterSlashings: []*pb.AttesterSlashing{},

View File

@ -234,7 +234,10 @@ func (sb *SimulatedBackend) RunStateTransitionTest(testCase *StateTestCase) erro
return fmt.Errorf("could not generate simulated beacon block %v", err)
}
latestRoot := depositsTrie.Root()
beaconState.LatestDepositRootHash32 = latestRoot[:]
beaconState.LatestEth1Data = &pb.Eth1Data{
DepositRootHash32: latestRoot[:],
BlockHash32: []byte{},
}
startTime := time.Now()
newState, err := state.ExecuteStateTransition(

View File

@ -35,36 +35,35 @@ func VerifyProposerSignature(
return nil
}
// ProcessDepositRoots processes the proof-of-work chain's receipts
// contained in a beacon block and appends them as candidate receipt roots
// in the beacon state.
// ProcessEth1Data is an operation performed on each
// beacon block to ensure the ETH1 data votes are processed
// into the beacon state.
//
// Official spec definition for processing deposit roots:
// If block.deposit_root is deposit_root_vote.deposit_root
// for some deposit_root_vote in state.deposit_root_votes,
// set deposit_root_vote.vote_count += 1.
// Otherwise, append to state.deposit_root_votes a
// new DepositRootVote(
// deposit_root=block.deposit_root,
// vote_count=1
// )
func ProcessDepositRoots(
beaconState *pb.BeaconState,
block *pb.BeaconBlock,
) *pb.BeaconState {
var newCandidateReceiptRoots []*pb.DepositRootVote
currentCandidateReceiptRoots := beaconState.DepositRootVotes
for idx, root := range currentCandidateReceiptRoots {
if bytes.Equal(block.DepositRootHash32, root.DepositRootHash32) {
currentCandidateReceiptRoots[idx].VoteCount++
} else {
newCandidateReceiptRoots = append(newCandidateReceiptRoots, &pb.DepositRootVote{
DepositRootHash32: block.DepositRootHash32,
VoteCount: 1,
})
// Official spec definition of ProcessEth1Data
// If block.eth1_data equals eth1_data_vote.eth1_data for some eth1_data_vote
// in state.eth1_data_votes, set eth1_data_vote.vote_count += 1.
// Otherwise, append to state.eth1_data_votes a new Eth1DataVote(eth1_data=block.eth1_data, vote_count=1).
func ProcessEth1Data(beaconState *pb.BeaconState, block *pb.BeaconBlock) *pb.BeaconState {
var eth1DataVoteAdded bool
for _, Eth1DataVote := range beaconState.Eth1DataVotes {
if bytes.Equal(Eth1DataVote.Eth1Data.BlockHash32, block.Eth1Data.BlockHash32) && bytes.Equal(Eth1DataVote.Eth1Data.DepositRootHash32, block.Eth1Data.DepositRootHash32) {
Eth1DataVote.VoteCount++
eth1DataVoteAdded = true
break
}
}
beaconState.DepositRootVotes = append(currentCandidateReceiptRoots, newCandidateReceiptRoots...)
if !eth1DataVoteAdded {
beaconState.Eth1DataVotes = append(
beaconState.Eth1DataVotes,
&pb.Eth1DataVote{
Eth1Data: block.Eth1Data,
VoteCount: 1,
},
)
}
return beaconState
}
@ -623,7 +622,7 @@ func ProcessValidatorDeposits(
func verifyDeposit(beaconState *pb.BeaconState, deposit *pb.Deposit) error {
// Verify Merkle proof of deposit and deposit trie root.
receiptRoot := bytesutil.ToBytes32(beaconState.LatestDepositRootHash32)
receiptRoot := bytesutil.ToBytes32(beaconState.LatestEth1Data.DepositRootHash32)
if ok := trieutil.VerifyMerkleBranch(
hashutil.Hash(deposit.DepositData),
deposit.MerkleBranchHash32S,

View File

@ -15,57 +15,6 @@ import (
"github.com/prysmaticlabs/prysm/shared/trieutil"
)
func TestProcessPOWReceiptRoots_SameRootHash(t *testing.T) {
beaconState := &pb.BeaconState{
DepositRootVotes: []*pb.DepositRootVote{
{
DepositRootHash32: []byte{1},
VoteCount: 5,
},
},
}
block := &pb.BeaconBlock{
DepositRootHash32: []byte{1},
}
beaconState = ProcessDepositRoots(beaconState, block)
newRoots := beaconState.DepositRootVotes
if newRoots[0].VoteCount != 6 {
t.Errorf("expected votes to increase from 5 to 6, received %d", newRoots[0].VoteCount)
}
}
func TestProcessPOWReceiptRoots_NewCandidateRecord(t *testing.T) {
beaconState := &pb.BeaconState{
DepositRootVotes: []*pb.DepositRootVote{
{
DepositRootHash32: []byte{0},
VoteCount: 5,
},
},
}
block := &pb.BeaconBlock{
DepositRootHash32: []byte{1},
}
beaconState = ProcessDepositRoots(beaconState, block)
newRoots := beaconState.DepositRootVotes
if len(newRoots) == 1 {
t.Error("expected new receipt roots to have length > 1")
}
if newRoots[1].VoteCount != 1 {
t.Errorf(
"expected new receipt roots to have a new element with votes = 1, received votes = %d",
newRoots[1].VoteCount,
)
}
if !bytes.Equal(newRoots[1].DepositRootHash32, []byte{1}) {
t.Errorf(
"expected new receipt roots to have a new element with root = %#x, received root = %#x",
[]byte{1},
newRoots[1].DepositRootHash32,
)
}
}
func TestProcessBlockRandao_UnequalBlockAndProposerRandao(t *testing.T) {
validators := make([]*pb.ValidatorRecord, config.EpochLength*2)
for i := 0; i < len(validators); i++ {
@ -136,6 +85,71 @@ func TestProcessBlockRandao_CreateRandaoMixAndUpdateProposer(t *testing.T) {
}
}
func TestProcessEth1Data_SameRootHash(t *testing.T) {
beaconState := &pb.BeaconState{
Eth1DataVotes: []*pb.Eth1DataVote{
&pb.Eth1DataVote{
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{1},
BlockHash32: []byte{2},
},
VoteCount: 5,
},
},
}
block := &pb.BeaconBlock{
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{1},
BlockHash32: []byte{2},
},
}
beaconState = ProcessEth1Data(beaconState, block)
newETH1DataVotes := beaconState.Eth1DataVotes
if newETH1DataVotes[0].VoteCount != 6 {
t.Errorf("expected votes to increase from 5 to 6, received %d", newETH1DataVotes[0].VoteCount)
}
}
func TestProcessEth1Data_NewDepositRootHash(t *testing.T) {
beaconState := &pb.BeaconState{
Eth1DataVotes: []*pb.Eth1DataVote{
&pb.Eth1DataVote{
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{0},
BlockHash32: []byte{1},
},
VoteCount: 5,
},
},
}
block := &pb.BeaconBlock{
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{2},
BlockHash32: []byte{3},
},
}
beaconState = ProcessEth1Data(beaconState, block)
newETH1DataVotes := beaconState.Eth1DataVotes
if len(newETH1DataVotes) <= 1 {
t.Error("expected new ETH1 data votes to have length > 1")
}
if newETH1DataVotes[1].VoteCount != 1 {
t.Errorf(
"expected new ETH1 data votes to have a new element with votes = 1, received votes = %d",
newETH1DataVotes[1].VoteCount,
)
}
if !bytes.Equal(newETH1DataVotes[1].Eth1Data.DepositRootHash32, []byte{2}) {
t.Errorf(
"expected new ETH1 data votes to have a new element with deposit root = %#x, received deposit root = %#x",
[]byte{1},
newETH1DataVotes[1].Eth1Data.DepositRootHash32,
)
}
}
func TestProcessProposerSlashings_ThresholdReached(t *testing.T) {
slashings := make([]*pb.ProposerSlashing, config.MaxProposerSlashings+1)
registry := []*pb.ValidatorRecord{}
@ -1190,7 +1204,10 @@ func TestProcessValidatorDeposits_MerkleBranchFailsVerification(t *testing.T) {
},
}
beaconState := &pb.BeaconState{
LatestDepositRootHash32: []byte{},
LatestEth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{0},
BlockHash32: []byte{1},
},
}
want := "merkle branch of deposit root did not verify"
if _, err := ProcessValidatorDeposits(
@ -1267,11 +1284,14 @@ func TestProcessValidatorDeposits_ProcessDepositHelperFuncFails(t *testing.T) {
balances := []uint64{0}
root := depositTrie.Root()
beaconState := &pb.BeaconState{
ValidatorRegistry: registry,
ValidatorBalances: balances,
LatestDepositRootHash32: root[:],
Slot: currentSlot,
GenesisTime: uint64(genesisTime),
ValidatorRegistry: registry,
ValidatorBalances: balances,
LatestEth1Data: &pb.Eth1Data{
DepositRootHash32: root[:],
BlockHash32: root[:],
},
Slot: currentSlot,
GenesisTime: uint64(genesisTime),
}
want := "expected withdrawal credentials to match"
if _, err := ProcessValidatorDeposits(
@ -1344,11 +1364,14 @@ func TestProcessValidatorDeposits_ProcessCorrectly(t *testing.T) {
balances := []uint64{0}
root := depositTrie.Root()
beaconState := &pb.BeaconState{
ValidatorRegistry: registry,
ValidatorBalances: balances,
LatestDepositRootHash32: root[:],
Slot: currentSlot,
GenesisTime: uint64(genesisTime),
ValidatorRegistry: registry,
ValidatorBalances: balances,
LatestEth1Data: &pb.Eth1Data{
DepositRootHash32: root[:],
BlockHash32: root[:],
},
Slot: currentSlot,
GenesisTime: uint64(genesisTime),
}
newState, err := ProcessValidatorDeposits(
beaconState,

View File

@ -47,7 +47,7 @@ func IsValidBlock(
}
if enablePOWChain {
h := common.BytesToHash(state.LatestDepositRootHash32)
h := common.BytesToHash(state.LatestEth1Data.DepositRootHash32)
powBlock, err := GetPOWBlock(ctx, h)
if err != nil {
return fmt.Errorf("unable to retrieve POW chain reference block %v", err)
@ -57,7 +57,7 @@ func IsValidBlock(
// The block pointed to by the state in state.processed_pow_receipt_root has
// been processed in the ETH 1.0 chain.
if powBlock == nil {
return fmt.Errorf("proof-of-Work chain reference in state does not exist %#x", state.LatestDepositRootHash32)
return fmt.Errorf("proof-of-Work chain reference in state does not exist %#x", state.LatestEth1Data.DepositRootHash32)
}
}

View File

@ -74,6 +74,10 @@ func TestBadBlock(t *testing.T) {
block.Slot = 4
powClient.blockExists = false
beaconState.LatestEth1Data = &pb.Eth1Data{
DepositRootHash32: []byte{2},
BlockHash32: []byte{3},
}
if err := IsValidBlock(ctx, beaconState, block, true,
db.HasBlock, powClient.BlockByHash, genesisTime); err == nil {
@ -107,9 +111,13 @@ func TestValidBlock(t *testing.T) {
genesisTime := params.BeaconConfig().GenesisTime
powClient.blockExists = true
beaconState.LatestEth1Data = &pb.Eth1Data{
DepositRootHash32: []byte{2},
BlockHash32: []byte{3},
}
if err := IsValidBlock(ctx, beaconState, block, true,
db.HasBlock, powClient.BlockByHash, genesisTime); err != nil {
t.Fatal(err)
}
}

View File

@ -25,13 +25,13 @@ func CanProcessEpoch(state *pb.BeaconState) bool {
return state.Slot%config.EpochLength == 0
}
// CanProcessDepositRoots checks the eligibility to process deposit root.
// The deposit root can be processed every DEPOSIT_ROOT_VOTING_PERIOD.
// CanProcessEth1Data checks the eligibility to process the eth1 data.
// The eth1 data can be processed every ETH1_DATA_VOTING_PERIOD.
//
// Spec pseudocode definition:
// If state.slot % DEPOSIT_ROOT_VOTING_PERIOD == 0:
func CanProcessDepositRoots(state *pb.BeaconState) bool {
return state.Slot%config.DepositRootVotingPeriod == 0
// If state.slot % ETH1_DATA_VOTING_PERIOD == 0:
func CanProcessEth1Data(state *pb.BeaconState) bool {
return state.Slot%config.Eth1DataVotingPeriod == 0
}
// CanProcessValidatorRegistry checks the eligibility to process validator registry.
@ -61,16 +61,27 @@ func CanProcessValidatorRegistry(state *pb.BeaconState) bool {
return true
}
// ProcessDeposits processes deposit roots by checking its vote count.
// With sufficient votes (>2*DEPOSIT_ROOT_VOTING_PERIOD), it then
// assigns root hash to processed receipt vote in state.
func ProcessDeposits(state *pb.BeaconState) *pb.BeaconState {
for _, receiptRoot := range state.DepositRootVotes {
if receiptRoot.VoteCount*2 > config.DepositRootVotingPeriod {
state.LatestDepositRootHash32 = receiptRoot.DepositRootHash32
// ProcessEth1Data processes eth1 block deposit roots by checking its vote count.
// With sufficient votes (>2*ETH1_DATA_VOTING_PERIOD), it then
// marks the voted Eth1 data as the latest data set.
//
// Official spec definition:
// if state.slot % ETH1_DATA_VOTING_PERIOD == 0:
// Set state.latest_eth1_data = eth1_data_vote.data
// if eth1_data_vote.vote_count * 2 > ETH1_DATA_VOTING_PERIOD for
// some eth1_data_vote in state.eth1_data_votes.
// Set state.eth1_data_votes = [].
//
func ProcessEth1Data(state *pb.BeaconState) *pb.BeaconState {
if state.Slot%config.Eth1DataVotingPeriod == 0 {
for _, eth1DataVote := range state.Eth1DataVotes {
if eth1DataVote.VoteCount*2 > config.Eth1DataVotingPeriod {
state.LatestEth1Data.DepositRootHash32 = eth1DataVote.Eth1Data.DepositRootHash32
state.LatestEth1Data.BlockHash32 = eth1DataVote.Eth1Data.BlockHash32
}
}
state.Eth1DataVotes = make([]*pb.Eth1DataVote, 0)
}
state.DepositRootVotes = make([]*pb.DepositRootVote, 0)
return state
}

View File

@ -51,78 +51,152 @@ func TestCanProcessEpoch(t *testing.T) {
}
}
func TestCanProcessReceiptRoots(t *testing.T) {
if config.DepositRootVotingPeriod != 1024 {
t.Errorf("PowReceiptRootVotingPeriod should be 1024 for these tests to pass")
func TestCanProcessEth1Data(t *testing.T) {
if config.Eth1DataVotingPeriod != 1024 {
t.Errorf("Eth1DataVotingPeriod should be 1024 for these tests to pass")
}
tests := []struct {
slot uint64
canProcessReceiptRoots bool
slot uint64
canProcessEth1Data bool
}{
{
slot: 1,
canProcessReceiptRoots: false,
slot: 1,
canProcessEth1Data: false,
},
{
slot: 1022,
canProcessReceiptRoots: false,
slot: 1022,
canProcessEth1Data: false,
},
{
slot: 1024,
canProcessReceiptRoots: true,
}, {
slot: 4096,
canProcessReceiptRoots: true,
}, {
slot: 234234,
canProcessReceiptRoots: false,
slot: 1024,
canProcessEth1Data: true,
},
{
slot: 4096,
canProcessEth1Data: true,
},
{
slot: 234234,
canProcessEth1Data: false,
},
}
for _, tt := range tests {
state := &pb.BeaconState{Slot: tt.slot}
if CanProcessDepositRoots(state) != tt.canProcessReceiptRoots {
if CanProcessEth1Data(state) != tt.canProcessEth1Data {
t.Errorf(
"CanProcessReceiptRoots(%d) = %v. Wanted %v",
"CanProcessEth1Data(%d) = %v. Wanted %v",
tt.slot,
CanProcessDepositRoots(state),
tt.canProcessReceiptRoots,
CanProcessEth1Data(state),
tt.canProcessEth1Data,
)
}
}
}
func TestProcessReceipt(t *testing.T) {
if config.DepositRootVotingPeriod != 1024 {
t.Errorf("PowReceiptRootVotingPeriod should be 1024 for these tests to pass")
func TestProcessEth1Data(t *testing.T) {
if config.Eth1DataVotingPeriod != 1024 {
t.Errorf("Eth1DataVotingPeriod should be 1024 for these tests to pass")
}
requiredVoteCount := config.DepositRootVotingPeriod
requiredVoteCount := config.Eth1DataVotingPeriod
state := &pb.BeaconState{
DepositRootVotes: []*pb.DepositRootVote{
{VoteCount: 0, DepositRootHash32: []byte{'A'}},
LatestEth1Data: &pb.Eth1Data{
DepositRootHash32: nil,
BlockHash32: nil,
},
Eth1DataVotes: []*pb.Eth1DataVote{
{
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{'A'},
BlockHash32: []byte{'B'},
},
VoteCount: 0,
},
// DepositRootHash32 ['B'] gets to process with sufficient vote count.
{VoteCount: requiredVoteCount/2 + 1, DepositRootHash32: []byte{'B'}},
{VoteCount: requiredVoteCount / 2, DepositRootHash32: []byte{'C'}},
{
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{'C'},
BlockHash32: []byte{'D'},
},
VoteCount: requiredVoteCount/2 + 1,
},
{
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{'E'},
BlockHash32: []byte{'F'},
},
VoteCount: requiredVoteCount / 2,
},
},
}
newState := ProcessDeposits(state)
if !bytes.Equal(newState.LatestDepositRootHash32, []byte{'B'}) {
t.Errorf("Incorrect LatestDepositRootHash32. Wanted: %v, got: %v",
[]byte{'B'}, newState.LatestDepositRootHash32)
newState := ProcessEth1Data(state)
if !bytes.Equal(newState.LatestEth1Data.DepositRootHash32, []byte{'C'}) {
t.Errorf("Incorrect DepositRootHash32. Wanted: %v, got: %v",
[]byte{'C'}, newState.LatestEth1Data.DepositRootHash32)
}
// Adding a new receipt root ['D'] which should be the new processed receipt root.
state.DepositRootVotes = append(state.DepositRootVotes,
&pb.DepositRootVote{VoteCount: requiredVoteCount,
DepositRootHash32: []byte{'D'}})
newState = ProcessDeposits(state)
if !bytes.Equal(newState.LatestDepositRootHash32, []byte{'D'}) {
t.Errorf("Incorrect LatestDepositRootHash32. Wanted: %v, got: %v",
[]byte{'D'}, newState.LatestDepositRootHash32)
state.Eth1DataVotes = append(state.Eth1DataVotes,
&pb.Eth1DataVote{
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{'G'},
BlockHash32: []byte{'H'},
},
VoteCount: requiredVoteCount,
},
)
newState = ProcessEth1Data(state)
if !bytes.Equal(newState.LatestEth1Data.DepositRootHash32, []byte{'G'}) {
t.Errorf("Incorrect DepositRootHash32. Wanted: %v, got: %v",
[]byte{'G'}, newState.LatestEth1Data.DepositRootHash32)
}
if len(newState.DepositRootVotes) != 0 {
t.Errorf("Failed to clean up DepositRootVotes slice. Length: %d",
len(newState.DepositRootVotes))
if len(newState.Eth1DataVotes) != 0 {
t.Errorf("Failed to clean up Eth1DataVotes slice. Length: %d",
len(newState.Eth1DataVotes))
}
}
func TestProcessEth1Data_InactionSlot(t *testing.T) {
if config.Eth1DataVotingPeriod != 1024 {
t.Errorf("Eth1DataVotingPeriod should be 1024 for these tests to pass")
}
requiredVoteCount := config.Eth1DataVotingPeriod
state := &pb.BeaconState{
Slot: 4,
LatestEth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{'A'},
BlockHash32: []byte{'B'},
},
Eth1DataVotes: []*pb.Eth1DataVote{
{
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{'C'},
BlockHash32: []byte{'D'},
},
VoteCount: requiredVoteCount/2 + 1,
},
{
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{'E'},
BlockHash32: []byte{'F'},
},
VoteCount: requiredVoteCount / 2,
},
{
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{'G'},
BlockHash32: []byte{'H'},
},
VoteCount: requiredVoteCount,
},
},
}
// Adding a new receipt root ['D'] which should be the new processed receipt root.
newState := ProcessEth1Data(state)
if !bytes.Equal(newState.LatestEth1Data.DepositRootHash32, []byte{'A'}) {
t.Errorf("Incorrect DepositRootHash32. Wanted: %v, got: %v",
[]byte{'A'}, newState.LatestEth1Data.DepositRootHash32)
}
}

View File

@ -119,9 +119,12 @@ func InitialBeaconState(
LatestAttestations: []*pb.PendingAttestationRecord{},
BatchedBlockRootHash32S: [][]byte{},
// deposit root.
LatestDepositRootHash32: processedPowReceiptRoot,
DepositRootVotes: []*pb.DepositRootVote{},
// Eth1 data.
LatestEth1Data: &pb.Eth1Data{
DepositRootHash32: processedPowReceiptRoot,
BlockHash32: []byte{},
},
Eth1DataVotes: []*pb.Eth1DataVote{},
}
// Process initial deposits.

View File

@ -150,11 +150,11 @@ func TestInitialBeaconState_Ok(t *testing.T) {
}
// deposit root checks.
if !bytes.Equal(state.LatestDepositRootHash32, processedPowReceiptRoot) {
t.Error("LatestDepositRootHash32 was not correctly initialized")
if !bytes.Equal(state.LatestEth1Data.DepositRootHash32, processedPowReceiptRoot) {
t.Error("LatestEth1Data DepositRootHash32 was not correctly initialized")
}
if !reflect.DeepEqual(state.DepositRootVotes, []*pb.DepositRootVote{}) {
t.Error("DepositRootVotes was not correctly initialized")
if !reflect.DeepEqual(state.Eth1DataVotes, []*pb.Eth1DataVote{}) {
t.Error("Eth1DataVotes was not correctly initialized")
}
}

View File

@ -74,7 +74,6 @@ func ProcessBlock(state *pb.BeaconState, block *pb.BeaconBlock, verifySignatures
}
}
var err error
state = b.ProcessDepositRoots(state, block)
state, err = b.ProcessBlockRandao(state, block)
if err != nil {
return nil, fmt.Errorf("could not verify and process block randao: %v", err)
@ -83,6 +82,7 @@ func ProcessBlock(state *pb.BeaconState, block *pb.BeaconBlock, verifySignatures
if err != nil {
return nil, fmt.Errorf("could not verify block proposer slashings: %v", err)
}
state = b.ProcessEth1Data(state, block)
state, err = b.ProcessAttesterSlashings(state, block, verifySignatures)
if err != nil {
return nil, fmt.Errorf("could not verify block attester slashings: %v", err)
@ -175,9 +175,9 @@ func ProcessEpoch(state *pb.BeaconState) (*pb.BeaconState, error) {
}
prevHeadAttestingBalances := e.TotalBalance(state, prevHeadAttesterIndices)
// Process receipt roots.
if e.CanProcessDepositRoots(state) {
e.ProcessDeposits(state)
// Process eth1 data
if e.CanProcessEth1Data(state) {
state = e.ProcessEth1Data(state)
}
// Update justification.

View File

@ -58,6 +58,10 @@ func TestProcessBlock_IncorrectProposerSlashing(t *testing.T) {
block := &pb.BeaconBlock{
Slot: 5,
RandaoRevealHash32: []byte{},
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{2},
BlockHash32: []byte{3},
},
Body: &pb.BeaconBlockBody{
ProposerSlashings: slashings,
},
@ -96,6 +100,10 @@ func TestProcessBlock_IncorrectAttesterSlashing(t *testing.T) {
block := &pb.BeaconBlock{
Slot: 5,
RandaoRevealHash32: []byte{},
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{2},
BlockHash32: []byte{3},
},
Body: &pb.BeaconBlockBody{
ProposerSlashings: slashings,
AttesterSlashings: attesterSlashings,
@ -157,6 +165,10 @@ func TestProcessBlock_IncorrectProcessBlockAttestations(t *testing.T) {
block := &pb.BeaconBlock{
Slot: 5,
RandaoRevealHash32: []byte{},
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{2},
BlockHash32: []byte{3},
},
Body: &pb.BeaconBlockBody{
ProposerSlashings: proposerSlashings,
AttesterSlashings: attesterSlashings,
@ -243,6 +255,10 @@ func TestProcessBlock_IncorrectProcessExits(t *testing.T) {
block := &pb.BeaconBlock{
Slot: 64,
RandaoRevealHash32: []byte{},
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{2},
BlockHash32: []byte{3},
},
Body: &pb.BeaconBlockBody{
ProposerSlashings: proposerSlashings,
AttesterSlashings: attesterSlashings,
@ -335,6 +351,10 @@ func TestProcessBlock_PassesProcessingConditions(t *testing.T) {
block := &pb.BeaconBlock{
Slot: 64,
RandaoRevealHash32: []byte{},
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{2},
BlockHash32: []byte{3},
},
Body: &pb.BeaconBlockBody{
ProposerSlashings: proposerSlashings,
AttesterSlashings: attesterSlashings,

View File

@ -7,6 +7,7 @@ package validators
import (
"bytes"
"fmt"
"github.com/gogo/protobuf/proto"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"

View File

@ -83,10 +83,13 @@ func TestSetBlockForInitialSync(t *testing.T) {
genericHash[0] = 'a'
block := &pb.BeaconBlock{
DepositRootHash32: []byte{1, 2, 3},
ParentRootHash32: genericHash,
Slot: uint64(1),
StateRootHash32: genericHash,
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{1, 2, 3},
BlockHash32: []byte{4, 5, 6},
},
ParentRootHash32: genericHash,
Slot: uint64(1),
StateRootHash32: genericHash,
}
blockResponse := &pb.BeaconBlockResponse{Block: block}
@ -163,10 +166,13 @@ func TestSavingBlocksInSync(t *testing.T) {
getBlockResponseMsg := func(Slot uint64) p2p.Message {
block := &pb.BeaconBlock{
DepositRootHash32: []byte{1, 2, 3},
ParentRootHash32: genericHash,
Slot: Slot,
StateRootHash32: beaconStateRootHash32[:],
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{1, 2, 3},
BlockHash32: []byte{4, 5, 6},
},
ParentRootHash32: genericHash,
Slot: Slot,
StateRootHash32: beaconStateRootHash32[:],
}
blockResponse := &pb.BeaconBlockResponse{
@ -273,10 +279,13 @@ func TestDelayChan(t *testing.T) {
beaconStateRootHash32 := hashutil.Hash(enc)
block := &pb.BeaconBlock{
DepositRootHash32: []byte{1, 2, 3},
ParentRootHash32: genericHash,
Slot: uint64(1),
StateRootHash32: beaconStateRootHash32[:],
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{1, 2, 3},
BlockHash32: []byte{4, 5, 6},
},
ParentRootHash32: genericHash,
Slot: uint64(1),
StateRootHash32: beaconStateRootHash32[:],
}
blockResponse := &pb.BeaconBlockResponse{
@ -353,10 +362,13 @@ func TestRequestBlocksBySlot(t *testing.T) {
getBlockResponseMsg := func(Slot uint64) (p2p.Message, [32]byte) {
block := &pb.BeaconBlock{
DepositRootHash32: []byte{1, 2, 3},
ParentRootHash32: genericHash,
Slot: Slot,
StateRootHash32: nil,
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{1, 2, 3},
BlockHash32: []byte{4, 5, 6},
},
ParentRootHash32: genericHash,
Slot: Slot,
StateRootHash32: nil,
}
blockResponse := &pb.BeaconBlockResponse{

View File

@ -155,9 +155,12 @@ func TestProcessBlock(t *testing.T) {
}
data := &pb.BeaconBlock{
DepositRootHash32: []byte{1, 2, 3, 4, 5},
ParentRootHash32: parentHash[:],
Slot: 1,
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{1, 2, 3, 4, 5},
BlockHash32: []byte{6, 7, 8, 9, 10},
},
ParentRootHash32: parentHash[:],
Slot: 1,
}
attestation := &pb.Attestation{
Data: &pb.AttestationData{
@ -235,9 +238,12 @@ func TestProcessMultipleBlocks(t *testing.T) {
}
data1 := &pb.BeaconBlock{
DepositRootHash32: []byte{1, 2, 3, 4, 5},
ParentRootHash32: parentHash[:],
Slot: 1,
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{1, 2, 3, 4, 5},
BlockHash32: []byte{6, 7, 8, 9, 10},
},
ParentRootHash32: parentHash[:],
Slot: 1,
}
responseBlock1 := &pb.BeaconBlockResponse{
@ -258,9 +264,12 @@ func TestProcessMultipleBlocks(t *testing.T) {
}
data2 := &pb.BeaconBlock{
DepositRootHash32: []byte{6, 7, 8, 9, 10},
ParentRootHash32: []byte{},
Slot: 1,
Eth1Data: &pb.Eth1Data{
DepositRootHash32: []byte{11, 12, 13, 14, 15},
BlockHash32: []byte{16, 17, 18, 19, 20},
},
ParentRootHash32: []byte{},
Slot: 1,
}
responseBlock2 := &pb.BeaconBlockResponse{

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@ package ethereum.beacon.p2p.v1;
import "proto/common/messages.proto";
message BeaconState {
// Validator registry [1-1000]
// Validator registry [1-1000]
repeated ValidatorRecord validator_registry = 1;
uint64 validator_registry_update_slot = 2;
bytes validator_registry_delta_chain_tip_hash32 = 3;
@ -20,7 +20,7 @@ message BeaconState {
bytes previous_epoch_seed_hash32 = 1009;
bytes current_epoch_seed_hash32 = 1010;
// Finality [2001-3000]
// Finality [2001-3000]
uint64 previous_justified_slot = 2001;
uint64 justified_slot = 2002;
uint64 justification_bitfield = 2003;
@ -34,9 +34,9 @@ message BeaconState {
repeated PendingAttestationRecord latest_attestations = 3006;
repeated bytes latest_index_root_hash32s = 3007;
// Ethereum 1.0 deposit root [4001-5000]
bytes latest_deposit_root_hash32 = 4001;
repeated DepositRootVote deposit_root_votes = 4002;
// Ethereum 1.0 chain data [4001-5000]
Eth1Data latest_eth1_data = 4001;
repeated Eth1DataVote eth1_data_votes = 4002;
// Miscellaneous [5001-6000]
uint64 genesis_time = 5001;
@ -50,11 +50,6 @@ message Fork {
uint64 slot = 3;
}
message DepositRootVote {
bytes deposit_root_hash32 = 1;
uint64 vote_count = 2;
}
message PendingAttestationRecord {
AttestationData data = 1;
bytes participation_bitfield = 2;
@ -126,7 +121,7 @@ message BeaconBlock {
bytes parent_root_hash32 = 2;
bytes state_root_hash32 = 3;
bytes randao_reveal_hash32 = 4;
bytes deposit_root_hash32 = 5;
Eth1Data eth1_data = 5;
repeated bytes signature = 6; // Type of [uint384]?
// Block Body
@ -205,3 +200,13 @@ message ValidatorRegistryDeltaBlock {
}
ValidatorRegistryDeltaFlags flag = 5;
}
message Eth1Data {
bytes deposit_root_hash32 = 1;
bytes block_hash32 = 2;
}
message Eth1DataVote {
Eth1Data eth1_data = 1;
uint64 vote_count = 2;
}

View File

@ -50,7 +50,7 @@ type BeaconChainConfig struct {
EpochLength uint64 // EpochLength is the number of slots in an epoch.
SeedLookahead uint64 // SeedLookahead is the duration of randao look ahead seed.
EntryExitDelay uint64 // EntryExitDelay is the duration a validator has to wait for entry and exit.
DepositRootVotingPeriod uint64 // DepositRootVotingPeriod defines how often the merkle root of deposit receipts get updated in beacon node.
Eth1DataVotingPeriod uint64 // Eth1DataVotingPeriod defines how often the merkle root of deposit receipts get updated in beacon node.
MinValidatorWithdrawalTime uint64 // MinValidatorWithdrawalTime is the shortest amount of time a validator can get the deposit out.
FarFutureSlot uint64 // FarFutureSlot represents a slot extremely far away in the future used as the default penalization slot for validators.
@ -122,7 +122,7 @@ var defaultBeaconConfig = &BeaconChainConfig{
EpochLength: 64,
SeedLookahead: 64,
EntryExitDelay: 256,
DepositRootVotingPeriod: 1024,
Eth1DataVotingPeriod: 1024,
// Reward and penalty quotients constants.
BaseRewardQuotient: 32,
@ -178,7 +178,7 @@ var demoBeaconConfig = &BeaconChainConfig{
EpochLength: defaultBeaconConfig.EpochLength,
SeedLookahead: defaultBeaconConfig.SeedLookahead,
EntryExitDelay: defaultBeaconConfig.EntryExitDelay,
DepositRootVotingPeriod: defaultBeaconConfig.DepositRootVotingPeriod,
Eth1DataVotingPeriod: defaultBeaconConfig.Eth1DataVotingPeriod,
// Reward and penalty quotients constants.
BaseRewardQuotient: defaultBeaconConfig.BaseRewardQuotient,