Fix a block proposal issue caused by incorrect merkle proofs
The key change here is that `addChunksAndGenMerkleProofs` is called with all pending deposits instead of just the deposits included in the block. The later was effectively producing merkle proofs against a different root.
This commit is contained in:
parent
b4defc9b4a
commit
027d2547cd
|
@ -455,7 +455,7 @@ proc advanceMerkleizer(eth1Chain: Eth1Chain,
|
||||||
|
|
||||||
return merkleizer.getChunkCount == depositIndex
|
return merkleizer.getChunkCount == depositIndex
|
||||||
|
|
||||||
proc getDepositsRange(eth1Chain: Eth1Chain, first, last: uint64): seq[Deposit] =
|
proc getDepositsRange(eth1Chain: Eth1Chain, first, last: uint64): seq[DepositData] =
|
||||||
# TODO It's possible to make this faster by performing binary search that
|
# TODO It's possible to make this faster by performing binary search that
|
||||||
# will locate the blocks holding the `first` and `last` indices.
|
# will locate the blocks holding the `first` and `last` indices.
|
||||||
# TODO There is an assumption here that the requested range will be present
|
# TODO There is an assumption here that the requested range will be present
|
||||||
|
@ -472,7 +472,7 @@ proc getDepositsRange(eth1Chain: Eth1Chain, first, last: uint64): seq[Deposit] =
|
||||||
for i in 0 ..< blk.deposits.lenu64:
|
for i in 0 ..< blk.deposits.lenu64:
|
||||||
let globalIdx = firstDepositIdxInBlk + i
|
let globalIdx = firstDepositIdxInBlk + i
|
||||||
if globalIdx >= first and globalIdx < last:
|
if globalIdx >= first and globalIdx < last:
|
||||||
result.add Deposit(data: blk.deposits[i])
|
result.add blk.deposits[i]
|
||||||
|
|
||||||
proc lowerBound(chain: Eth1Chain, depositCount: uint64): Eth1Block =
|
proc lowerBound(chain: Eth1Chain, depositCount: uint64): Eth1Block =
|
||||||
# TODO: This can be replaced with a proper binary search in the
|
# TODO: This can be replaced with a proper binary search in the
|
||||||
|
@ -565,21 +565,22 @@ proc getBlockProposalData*(m: Eth1Monitor,
|
||||||
|
|
||||||
if pendingDepositsCount > 0:
|
if pendingDepositsCount > 0:
|
||||||
if hasLatestDeposits:
|
if hasLatestDeposits:
|
||||||
let totalDepositsInNewBlock = min(MAX_DEPOSITS, pendingDepositsCount)
|
let
|
||||||
var deposits = m.eth1Chain.getDepositsRange(
|
totalDepositsInNewBlock = min(MAX_DEPOSITS, pendingDepositsCount)
|
||||||
state.eth1_deposit_index,
|
deposits = m.eth1Chain.getDepositsRange(
|
||||||
state.eth1_deposit_index + totalDepositsInNewBlock)
|
state.eth1_deposit_index,
|
||||||
let depositRoots = mapIt(deposits, hash_tree_root(it.data))
|
state.eth1_deposit_index + pendingDepositsCount)
|
||||||
|
depositRoots = mapIt(deposits, hash_tree_root(it))
|
||||||
|
|
||||||
var scratchMerkleizer = copy m.eth2FinalizedDepositsMerkleizer
|
var scratchMerkleizer = copy m.eth2FinalizedDepositsMerkleizer
|
||||||
if m.eth1Chain.advanceMerkleizer(scratchMerkleizer, state.eth1_deposit_index):
|
if m.eth1Chain.advanceMerkleizer(scratchMerkleizer, state.eth1_deposit_index):
|
||||||
let proofs = scratchMerkleizer.addChunksAndGenMerkleProofs(depositRoots)
|
let proofs = scratchMerkleizer.addChunksAndGenMerkleProofs(depositRoots)
|
||||||
for i in 0 ..< deposits.lenu64:
|
for i in 0 ..< totalDepositsInNewBlock:
|
||||||
deposits[i].proof[0..31] = proofs.getProof(i.int)
|
var proof: array[33, Eth2Digest]
|
||||||
deposits[i].proof[32].data[0..7] =
|
proof[0..31] = proofs.getProof(i.int)
|
||||||
toBytesLE uint64(state.eth1_deposit_index + i + 1)
|
proof[32] = default(Eth2Digest)
|
||||||
|
proof[32].data[0..7] = toBytesLE uint64(result.vote.deposit_count)
|
||||||
swap(result.deposits, deposits)
|
result.deposits.add Deposit(data: deposits[i], proof: proof)
|
||||||
else:
|
else:
|
||||||
error "The Eth1 chain is in inconsistent state" # This should not really happen
|
error "The Eth1 chain is in inconsistent state" # This should not really happen
|
||||||
result.hasMissingDeposits = true
|
result.hasMissingDeposits = true
|
||||||
|
|
|
@ -34,7 +34,9 @@ func attachMerkleProofs*(deposits: var openArray[Deposit]) =
|
||||||
template getProof*(proofs: seq[Eth2Digest], idxParam: int): openArray[Eth2Digest] =
|
template getProof*(proofs: seq[Eth2Digest], idxParam: int): openArray[Eth2Digest] =
|
||||||
let
|
let
|
||||||
idx = idxParam
|
idx = idxParam
|
||||||
startIdx = idx * DEPOSIT_CONTRACT_TREE_DEPTH
|
## TODO: It's surprising that we have to do +1 here.
|
||||||
|
## It seems that `depositContractLimit` is set too high.
|
||||||
|
startIdx = idx * (DEPOSIT_CONTRACT_TREE_DEPTH + 1)
|
||||||
endIdx = startIdx + DEPOSIT_CONTRACT_TREE_DEPTH - 1
|
endIdx = startIdx + DEPOSIT_CONTRACT_TREE_DEPTH - 1
|
||||||
proofs.toOpenArray(startIdx, endIdx)
|
proofs.toOpenArray(startIdx, endIdx)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue