Skip to content

Commit

Permalink
Fix invalid merkle proof generation when there is a large number of u…
Browse files Browse the repository at this point in the history
…nprocessed deposits (#3607)
  • Loading branch information
zah committed Apr 27, 2022
1 parent 0d5bbbc commit abfef0a
Showing 1 changed file with 17 additions and 11 deletions.
28 changes: 17 additions & 11 deletions beacon_chain/eth1/eth1_monitor.nim
Expand Up @@ -817,16 +817,24 @@ proc getBlockProposalData*(chain: var Eth1Chain,
depositsRoot = vote.deposit_root,
localDeposits = getStateField(state, eth1_data).deposit_count

var pendingDepositsCount =
getStateField(state, eth1_data).deposit_count -
getStateField(state, eth1_deposit_index)
let
stateDepositIdx = getStateField(state, eth1_deposit_index)
stateDepositsCount = getStateField(state, eth1_data).deposit_count

# A valid state should never have this condition, but it doesn't hurt
# to be extra defensive here because we are working with uint types
var pendingDepositsCount = if stateDepositsCount > stateDepositIdx:
stateDepositsCount - stateDepositIdx
else:
0

if otherVotesCountTable.len > 0:
let (winningVote, votes) = otherVotesCountTable.largest
debug "Voting on eth1 head with majority", votes
result.vote = winningVote
if uint64((votes + 1) * 2) > SLOTS_PER_ETH1_VOTING_PERIOD:
pendingDepositsCount = winningVote.deposit_count -
getStateField(state, eth1_deposit_index)
pendingDepositsCount = winningVote.deposit_count - stateDepositIdx

else:
let latestBlock = chain.latestCandidateBlock(periodStart)
if latestBlock == nil:
Expand All @@ -840,20 +848,18 @@ proc getBlockProposalData*(chain: var Eth1Chain,
if hasLatestDeposits:
let
totalDepositsInNewBlock = min(MAX_DEPOSITS, pendingDepositsCount)
deposits = chain.getDepositsRange(
getStateField(state, eth1_deposit_index),
getStateField(state, eth1_deposit_index) + pendingDepositsCount)
postStateDepositIdx = stateDepositIdx + pendingDepositsCount
deposits = chain.getDepositsRange(stateDepositIdx, postStateDepositIdx)
depositRoots = mapIt(deposits, hash_tree_root(it))

var scratchMerkleizer = copy chain.finalizedDepositsMerkleizer
if chain.advanceMerkleizer(
scratchMerkleizer, getStateField(state, eth1_deposit_index)):
if chain.advanceMerkleizer(scratchMerkleizer, stateDepositIdx):
let proofs = scratchMerkleizer.addChunksAndGenMerkleProofs(depositRoots)
for i in 0 ..< totalDepositsInNewBlock:
var proof: array[33, Eth2Digest]
proof[0..31] = proofs.getProof(i.int)
proof[32] = default(Eth2Digest)
proof[32].data[0..7] = toBytesLE uint64(result.vote.deposit_count)
proof[32].data[0..7] = toBytesLE uint64(postStateDepositIdx)
result.deposits.add Deposit(data: deposits[i], proof: proof)
else:
error "The Eth1 chain is in inconsistent state" # This should not really happen
Expand Down

0 comments on commit abfef0a

Please sign in to comment.