-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Implement Eth1Data RPC Server Functionality #1615
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1615 +/- ##
==========================================
- Coverage 71.56% 71.15% -0.42%
==========================================
Files 94 94
Lines 6500 6562 +62
==========================================
+ Hits 4652 4669 +17
- Misses 1439 1482 +43
- Partials 409 411 +2 |
Codecov Report
@@ Coverage Diff @@
## master #1615 +/- ##
==========================================
+ Coverage 70.77% 71.12% +0.34%
==========================================
Files 98 94 -4
Lines 7060 6652 -408
==========================================
- Hits 4997 4731 -266
+ Misses 1626 1498 -128
+ Partials 437 423 -14 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One comment on how we get depositRoot
when dataVoteObjects is empty
beacon-chain/rpc/beacon_server.go
Outdated
for _, vote := range beaconState.Eth1DataVotes { | ||
eth1Hash := bytesutil.ToBytes32(vote.Eth1Data.BlockHash32) | ||
// Verify the block from the vote's block hash exists in the eth1.0 chain and fetch its height. | ||
blockExists, blockNumber, err := bs.powChainService.BlockExists(eth1Hash) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of blockNumber
, we should try to use blockHeight
so its consistent with the rest
// at the block defined by vote.eth1_data.block_hash. | ||
isBehindFollowDistance := blockNumber.Add(blockNumber, big.NewInt(eth1FollowDistance)).Cmp(currentHeight) == -1 | ||
isAheadStateLatestEth1Data := blockNumber.Cmp(stateLatestEth1Height) == 1 | ||
if blockExists && isBehindFollowDistance && isAheadStateLatestEth1Data { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this whole check could use some better verbosity. If a Eth1DataVote
does not get included, which condition failed and what are the numbers (how many blocks it needs to wait for it to get included.. etc)
beacon-chain/powchain/service.go
Outdated
func (w *Web3Service) DepositRoot() [32]byte { | ||
return w.depositTrie.Root() | ||
} | ||
|
||
// LatestBlockNumber in the ETH1.0 chain. | ||
func (w *Web3Service) LatestBlockNumber() *big.Int { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think LatestBlockHeight
sounds better here...
if err != nil { | ||
return nil, fmt.Errorf("could not fetch ETH1_FOLLOW_DISTANCE ancestor: %v", err) | ||
} | ||
depositRoot := bs.powChainService.DepositRoot() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is correct. We should get the depositRoot
that is referenced by blockHash
from ancestorHeight
.
bs.powChainService.DepositRoot() just returns you the latest deposit root right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@terenc3t there is no way to actually do that now, we dont keep a list of all the previous deposit roots. When we get a deposit log we just update the deposit trie and create a new root. Also deposit root is dependant on the merkle index of the deposit not the block number. We could have multiple deposits in a block , generating multiple deposit roots
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's fine we can't do this now but where is the comment or note saying our implementation does diverge from the spec
beacon-chain/rpc/beacon_server.go
Outdated
if err != nil { | ||
return nil, fmt.Errorf("could not fetch beacon state: %v", err) | ||
} | ||
dataVoteObjects := []*pbp2p.Eth1DataVote{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
optional:
s/dataVoteObjects/voteObjects
or
s/dataVoteOBjects/dataVotes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dataVotes
sounds better imo
beacon-chain/powchain/service.go
Outdated
@@ -199,6 +205,18 @@ func (w *Web3Service) LatestBlockHash() common.Hash { | |||
return w.blockHash | |||
} | |||
|
|||
// BlockExists -- | |||
// Unimplemented, Work in Progress. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add the issue number referencing the work here as a TODO, same as below
beacon-chain/rpc/beacon_server.go
Outdated
if err != nil { | ||
return nil, fmt.Errorf("could not fetch beacon state: %v", err) | ||
} | ||
dataVoteObjects := []*pbp2p.Eth1DataVote{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dataVotes
sounds better imo
beacon-chain/rpc/beacon_server.go
Outdated
for _, vote := range beaconState.Eth1DataVotes { | ||
eth1Hash := bytesutil.ToBytes32(vote.Eth1Data.BlockHash32) | ||
// Verify the block from the vote's block hash exists in the eth1.0 chain and fetch its height. | ||
blockExists, blockNumber, err := bs.powChainService.BlockExists(eth1Hash) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if blockExists == false
we can skip the operations below
// Let dataVoteObjects be the set of Eth1DataVote objects vote in state.eth1_data_votes where: | ||
// vote.eth1_data.block_hash is the hash of an eth1.0 block that is: | ||
// (i) part of the canonical chain | ||
// (ii) >= ETH1_FOLLOW_DISTANCE blocks behind the head |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the code below represents > ETH1_FOLLOW_DISTANCE blocks behind the head
not
>= ETH1_FOLLOW_DISTANCE blocks behind the head
.
if err != nil { | ||
return nil, fmt.Errorf("could not fetch ETH1_FOLLOW_DISTANCE ancestor: %v", err) | ||
} | ||
depositRoot := bs.powChainService.DepositRoot() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@terenc3t there is no way to actually do that now, we dont keep a list of all the previous deposit roots. When we get a deposit log we just update the deposit trie and create a new root. Also deposit root is dependant on the merkle index of the deposit not the block number. We could have multiple deposits in a block , generating multiple deposit roots
@rauljordan let me know when this is ready again |
This is part of #1565 and resolves #1463, and is related to #1456
Description
This PR implements the Eth1Data RPC server functionality in our beacon server for proposers necessary information related to Eth1Data votes to include in their blocks. This PR uses an interface for required information from the powchain service such as
CurrentHeight
andBlockExists
. Those functions will be implemented in a separate PR. This PR only concerns itself with thebeacon-chain/rpc
package to keep the scope small and easier to review.This PR implements the logic found in the honest validator specification as of commit hash 375659dc6c92ddcbf1682a024f9afc4fb24335c6 below:
Eth1 Data
block.eth1_data
is a mechanism used by block proposers vote on a recent Ethereum 1.0 block hash and an associated deposit root found in the Ethereum 1.0 deposit contract. When consensus is formed,state.latest_eth1_data
is updated, and validator deposits up to this root can be processed. The deposit root can be calculated by calling theget_deposit_root()
function of the deposit contract using the post-state of the block hash.D
be the set ofEth1DataVote
objectsvote
instate.eth1_data_votes
where:vote.eth1_data.block_hash
is the hash of an eth1.0 block that is (i) part of the canonical chain, (ii) >=ETH1_FOLLOW_DISTANCE
blocks behind the head, and (iii) newer thanstate.latest_eth1_data.block_data
.vote.eth1_data.deposit_root
is the deposit root of the eth1.0 deposit contract at the block defined byvote.eth1_data.block_hash
.D
is empty:block_hash
be the block hash of theETH1_FOLLOW_DISTANCE
'th ancestor of the head of the canonical eth1.0 chain.deposit_root
be the deposit root of the eth1.0 deposit contract in the post-state of the block referenced byblock_hash
D
is nonempty:best_vote
be the member ofD
that has the highestvote.eth1_data.vote_count
, breaking ties by favoring block hashes with higher associated block height.block_hash = best_vote.eth1_data.block_hash
.deposit_root = best_vote.eth1_data.deposit_root
.block.eth1_data = Eth1Data(deposit_root=deposit_root, block_hash=block_hash)
.