Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make ETH1Data Determination More Strict #5944

Merged
merged 10 commits into from
May 22, 2020
9 changes: 9 additions & 0 deletions beacon-chain/blockchain/chain_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type HeadFetcher interface {
HeadValidatorsIndices(epoch uint64) ([]uint64, error)
HeadSeed(epoch uint64) ([32]byte, error)
HeadGenesisValidatorRoot() [32]byte
HeadETH1Data() *ethpb.Eth1Data
}

// ForkFetcher retrieves the current fork information of the Ethereum beacon chain.
Expand Down Expand Up @@ -196,6 +197,14 @@ func (s *Service) HeadGenesisValidatorRoot() [32]byte {
return s.headGenesisValidatorRoot()
}

// HeadETH1Data returns the eth1data of the current head state.
func (s *Service) HeadETH1Data() *ethpb.Eth1Data {
if !s.hasHeadState() {
return &ethpb.Eth1Data{}
}
return s.head.state.Eth1Data()
}

// GenesisTime returns the genesis time of beacon chain.
func (s *Service) GenesisTime() time.Time {
return s.genesisTime
Expand Down
6 changes: 6 additions & 0 deletions beacon-chain/blockchain/testing/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type ChainService struct {
Genesis time.Time
ValidatorsRoot [32]byte
Fork *pb.Fork
ETH1Data *ethpb.Eth1Data
DB db.Database
stateNotifier statefeed.Notifier
blockNotifier blockfeed.Notifier
Expand Down Expand Up @@ -220,6 +221,11 @@ func (ms *ChainService) HeadSeed(epoch uint64) ([32]byte, error) {
return helpers.Seed(ms.State, epoch, params.BeaconConfig().DomainBeaconAttester)
}

// HeadETH1Data provides the current ETH1Data of the head state.
func (ms *ChainService) HeadETH1Data() *ethpb.Eth1Data {
return ms.ETH1Data
}

// GenesisTime mocks the same method in the chain service.
func (ms *ChainService) GenesisTime() time.Time {
return ms.Genesis
Expand Down
5 changes: 5 additions & 0 deletions beacon-chain/rpc/validator/proposer.go
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,11 @@ func (vs *Server) defaultEth1DataResponse(ctx context.Context, currentHeight *bi
if depositsTillHeight == 0 {
return vs.ChainStartFetcher.ChainStartEth1Data(), nil
}
// Check for the validity of deposit count.
currentETH1Data := vs.HeadFetcher.HeadETH1Data()
if depositsTillHeight < currentETH1Data.DepositCount {
return currentETH1Data, nil
}
return &ethpb.Eth1Data{
DepositRoot: depositRoot[:],
BlockHash: blockHash[:],
Expand Down
65 changes: 65 additions & 0 deletions beacon-chain/rpc/validator/proposer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1239,6 +1239,71 @@ func TestEth1Data(t *testing.T) {
}
}

func TestEth1Data_SmallerDepositCount(t *testing.T) {
slot := uint64(10000)
deps := []*dbpb.DepositContainer{
{
Index: 0,
Eth1BlockHeight: 8,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte("a"),
Signature: make([]byte, 96),
WithdrawalCredentials: make([]byte, 32),
}},
},
{
Index: 1,
Eth1BlockHeight: 14,
Deposit: &ethpb.Deposit{
Data: &ethpb.Deposit_Data{
PublicKey: []byte("b"),
Signature: make([]byte, 96),
WithdrawalCredentials: make([]byte, 32),
}},
},
}
depositTrie, err := trieutil.NewTrie(int(params.BeaconConfig().DepositContractTreeDepth))
if err != nil {
t.Fatalf("could not setup deposit trie: %v", err)
}
depositCache := depositcache.NewDepositCache()
for _, dp := range deps {
depositCache.InsertDeposit(context.Background(), dp.Deposit, dp.Eth1BlockHeight, dp.Index, depositTrie.Root())
}

p := &mockPOW.POWChain{
BlockNumberByHeight: map[uint64]*big.Int{
slot * params.BeaconConfig().SecondsPerSlot: big.NewInt(4096),
},
HashesByHeight: map[int][]byte{
4080: []byte("4080"),
},
Eth1Data: &ethpb.Eth1Data{
DepositCount: 55,
},
}
ps := &Server{
ChainStartFetcher: p,
Eth1InfoFetcher: p,
Eth1BlockFetcher: p,
HeadFetcher: &mock.ChainService{ETH1Data: &ethpb.Eth1Data{DepositCount: 10}},
DepositFetcher: depositCache,
}

ctx := context.Background()
eth1Data, err := ps.eth1Data(ctx, slot)
if err != nil {
t.Fatal(err)
}

// Will default to 10 as the current deposit count in the
// cache is only 2.
if eth1Data.DepositCount != 10 {
t.Errorf("Expected deposit count to be 10 but got %d", eth1Data.DepositCount)
}
}

func TestEth1Data_MockEnabled(t *testing.T) {
db := dbutil.SetupDB(t)
// If a mock eth1 data votes is specified, we use the following for the
Expand Down