Skip to content

Commit 39f5019

Browse files
committed
Fix incorrect DepositTree finalization when 0 finalized deposits
1 parent c89c88b commit 39f5019

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

ethereum/pow/merkletree/src/main/java/tech/pegasys/teku/ethereum/pow/merkletree/DepositTree.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ public void finalize(final Eth1Data eth1Data, final UInt64 blockHeight) {
9595
checkArgument(
9696
totalDepositCount >= eth1Data.getDepositCount().longValue(),
9797
"Merkle tree does not contain all deposits to be finalized");
98+
if (eth1Data.getDepositCount().equals(UInt64.ZERO)) {
99+
return;
100+
}
98101
finalizedExecutionBlock =
99102
Optional.of(new BlockHashAndHeight(eth1Data.getBlockHash(), blockHeight));
100103
finalizedDepositCount = eth1Data.getDepositCount().longValue();

ethereum/pow/merkletree/src/test/java/tech/pegasys/teku/ethereum/pow/merkletree/DepositTreeTest.java

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919
import static tech.pegasys.teku.ethereum.pow.api.DepositConstants.DEPOSIT_CONTRACT_TREE_DEPTH;
2020

2121
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
22+
import java.util.ArrayList;
2223
import java.util.List;
2324
import java.util.Optional;
25+
import java.util.function.Function;
2426
import org.apache.tuweni.bytes.Bytes32;
2527
import org.junit.jupiter.api.Test;
2628
import org.junit.jupiter.params.ParameterizedTest;
@@ -54,13 +56,58 @@ void shouldGenerateSnapshots(final int nonFinalizedDepositCount) throws Exceptio
5456

5557
if (i >= nonFinalizedDepositCount) {
5658
final DepositTestCase finalisingTestCase = testCases.get(i - nonFinalizedDepositCount);
57-
depositTree.finalize(finalisingTestCase.getEth1Data(), finalisingTestCase.getBlockHeight());
59+
final Eth1Data correctEth1Data = finalisingTestCase.getEth1Data();
60+
depositTree.finalize(
61+
new Eth1Data(
62+
correctEth1Data.getDepositRoot(),
63+
correctEth1Data.getDepositCount().minus(1),
64+
correctEth1Data.getBlockHash()),
65+
finalisingTestCase.getBlockHeight());
5866
final Optional<DepositTreeSnapshot> snapshotOptional = depositTree.getSnapshot();
5967
assertThat(snapshotOptional).contains(finalisingTestCase.getSnapshot());
6068
}
6169
}
6270
}
6371

72+
@Test
73+
void snapshotShouldHaveCorrectDepositCount() {
74+
final int depositsCount = 10;
75+
final Bytes32 depositRoot = Bytes32.random();
76+
final Bytes32 blockHash = Bytes32.random();
77+
final Function<Integer, Eth1Data> eth1Generator =
78+
deposits -> new Eth1Data(depositRoot, UInt64.valueOf(deposits), blockHash);
79+
80+
final List<Bytes32> leafs = new ArrayList<>();
81+
for (int i = 0; i < depositsCount; ++i) {
82+
leafs.add(Bytes32.random());
83+
}
84+
final DepositTree fullTree = new DepositTree();
85+
leafs.forEach(fullTree::pushLeaf);
86+
fullTree.finalize(eth1Generator.apply(depositsCount), UInt64.ZERO);
87+
final DepositTreeSnapshot fullTreeSnapshot = fullTree.getSnapshot().orElseThrow();
88+
89+
for (int finalized = 0; finalized <= depositsCount; ++finalized) {
90+
final DepositTree customTree = new DepositTree();
91+
for (int j = 0; j < depositsCount; ++j) {
92+
customTree.pushLeaf(leafs.get(j));
93+
}
94+
customTree.finalize(eth1Generator.apply(finalized), UInt64.ZERO);
95+
final Optional<DepositTreeSnapshot> customTreeSnapshot = customTree.getSnapshot();
96+
System.out.println(customTreeSnapshot);
97+
switch (finalized) {
98+
case 0 -> assertThat(customTreeSnapshot).isEmpty();
99+
case depositsCount -> assertThat(customTreeSnapshot).contains(fullTreeSnapshot);
100+
default -> {
101+
assertThat(customTreeSnapshot).isPresent();
102+
final DepositTreeSnapshot snapshot = customTreeSnapshot.get();
103+
assertThat(snapshot.getDepositCount()).isEqualTo(finalized);
104+
assertThat(snapshot.getDepositRoot()).isNotEqualTo(fullTreeSnapshot.getDepositRoot());
105+
assertThat(snapshot.getFinalized()).isNotEqualTo(fullTreeSnapshot.getFinalized());
106+
}
107+
}
108+
}
109+
}
110+
64111
@Test
65112
void shouldRestoreFromSnapshots() throws Exception {
66113
final List<DepositTestCase> testCases = loadEipTestCases();

0 commit comments

Comments
 (0)