Skip to content

Commit dcd3bc0

Browse files
authored
Revert "Implement more memory efficient deposit merkle tree (#5501)" (#5603)
This reverts commit 784799f.
1 parent d4de38c commit dcd3bc0

File tree

21 files changed

+152
-10455
lines changed

21 files changed

+152
-10455
lines changed

CHANGELOG.md

-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ For information on changes in released versions of Teku, see the [releases page]
1818

1919
### Additions and Improvements
2020
- Upated ropsten testnet config to include extremely high TTD and enable proposer boost.
21-
- Reduced memory requirements for storing the deposit merkle tree.
2221
- Changed the default maximum peers count from 74 to 100 (`--p2p-peer-upper-bound 74` was old setting)
2322
- Update proposer boost weighting to 40%.
2423
- Update `BeaconBlocksByRange` to only return the first block if the step is greater than 1, in line with 1.20 spec.

beacon/validator/build.gradle

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ dependencies {
1010
implementation project(':ethereum:core')
1111
implementation project(':ethereum:events')
1212
implementation project(':ethereum:pow:api')
13-
implementation project(':ethereum:pow:merkletree')
1413
implementation project(':ethereum:spec')
1514
implementation project(':networking:eth2')
1615
implementation project(':infrastructure:logging')

beacon/validator/src/main/java/tech/pegasys/teku/validator/coordinator/DepositProvider.java

+23-27
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
package tech.pegasys.teku.validator.coordinator;
1515

16-
import static java.util.Collections.emptyList;
1716
import static tech.pegasys.teku.infrastructure.unsigned.UInt64.ONE;
1817

1918
import java.util.NavigableMap;
@@ -28,7 +27,6 @@
2827
import tech.pegasys.teku.ethereum.pow.api.DepositsFromBlockEvent;
2928
import tech.pegasys.teku.ethereum.pow.api.Eth1EventsChannel;
3029
import tech.pegasys.teku.ethereum.pow.api.MinGenesisTimeBlockEvent;
31-
import tech.pegasys.teku.ethereum.pow.merkletree.DepositTree;
3230
import tech.pegasys.teku.infrastructure.logging.EventLogger;
3331
import tech.pegasys.teku.infrastructure.metrics.TekuMetricCategory;
3432
import tech.pegasys.teku.infrastructure.ssz.SszList;
@@ -43,6 +41,8 @@
4341
import tech.pegasys.teku.spec.datastructures.state.Checkpoint;
4442
import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState;
4543
import tech.pegasys.teku.spec.datastructures.util.DepositUtil;
44+
import tech.pegasys.teku.spec.datastructures.util.MerkleTree;
45+
import tech.pegasys.teku.spec.datastructures.util.OptimizedMerkleTree;
4646
import tech.pegasys.teku.storage.api.FinalizedCheckpointChannel;
4747
import tech.pegasys.teku.storage.client.RecentChainData;
4848

@@ -55,7 +55,7 @@ public class DepositProvider
5555

5656
private final RecentChainData recentChainData;
5757
private final Eth1DataCache eth1DataCache;
58-
private final DepositTree depositMerkleTree;
58+
private final MerkleTree depositMerkleTree;
5959

6060
private final NavigableMap<UInt64, DepositWithIndex> depositNavigableMap = new TreeMap<>();
6161
private final Counter depositCounter;
@@ -77,7 +77,8 @@ public DepositProvider(
7777
this.eth1DataCache = eth1DataCache;
7878
this.spec = spec;
7979
depositUtil = new DepositUtil(spec);
80-
depositMerkleTree = new DepositTree();
80+
depositMerkleTree =
81+
new OptimizedMerkleTree(spec.getGenesisSpecConfig().getDepositContractTreeDepth());
8182
depositCounter =
8283
metricsSystem.createCounter(
8384
TekuMetricCategory.BEACON,
@@ -97,30 +98,32 @@ public synchronized void onDepositsFromBlock(DepositsFromBlockEvent event) {
9798
}
9899

99100
depositNavigableMap.put(deposit.getIndex(), deposit);
100-
depositMerkleTree.pushLeaf(deposit.getData().hashTreeRoot());
101+
depositMerkleTree.add(deposit.getData().hashTreeRoot());
101102
});
102103
depositCounter.inc(event.getDeposits().size());
103104
eth1DataCache.onBlockWithDeposit(
104105
event.getBlockTimestamp(),
105106
new Eth1Data(
106107
depositMerkleTree.getRoot(),
107-
UInt64.valueOf(depositMerkleTree.getDepositCount()),
108+
UInt64.valueOf(depositMerkleTree.getNumberOfLeaves()),
108109
event.getBlockHash()));
109110
}
110111

111112
@Override
112113
public void onNewFinalizedCheckpoint(
113114
final Checkpoint checkpoint, final boolean fromOptimisticBlock) {
114-
final BeaconState finalizedState = recentChainData.getStore().getLatestFinalized().getState();
115-
final UInt64 depositIndex = finalizedState.getEth1DepositIndex();
116-
pruneDeposits(depositIndex);
117-
synchronized (this) {
118-
if (depositIndex.isGreaterThanOrEqualTo(finalizedState.getEth1Data().getDepositCount())
119-
&& depositMerkleTree.getDepositCount()
120-
>= finalizedState.getEth1Data().getDepositCount().longValue()) {
121-
depositMerkleTree.finalize(finalizedState.getEth1Data());
122-
}
123-
}
115+
recentChainData
116+
.retrieveBlockState(checkpoint.getRoot())
117+
.thenAccept(
118+
finalizedState -> {
119+
if (finalizedState.isEmpty()) {
120+
LOG.error("Finalized checkpoint state not found.");
121+
return;
122+
}
123+
final UInt64 depositIndex = finalizedState.get().getEth1DepositIndex();
124+
pruneDeposits(depositIndex);
125+
})
126+
.reportExceptions();
124127
}
125128

126129
private synchronized void pruneDeposits(final UInt64 toIndex) {
@@ -213,22 +216,13 @@ public synchronized int getDepositMapSize() {
213216
* @param fromDepositIndex inclusive
214217
* @param toDepositIndex exclusive
215218
* @param eth1DepositCount number of deposits in the merkle tree according to Eth1Data in state
219+
* @return
216220
*/
217221
private SszList<Deposit> getDepositsWithProof(
218222
UInt64 fromDepositIndex, UInt64 toDepositIndex, UInt64 eth1DepositCount, long maxDeposits) {
219223
final AtomicReference<UInt64> expectedDepositIndex = new AtomicReference<>(fromDepositIndex);
220224
final SszListSchema<Deposit, ?> depositsSchema = depositsSchemaCache.get(maxDeposits);
221225
final SszBytes32VectorSchema<?> depositProofSchema = Deposit.SSZ_SCHEMA.getProofSchema();
222-
// No deposits to include so don't bother rewinding the merkle tree.
223-
if (fromDepositIndex.equals(toDepositIndex)) {
224-
return depositsSchema.createFromElements(emptyList());
225-
}
226-
if (depositMerkleTree.getDepositCount() < eth1DepositCount.intValue()) {
227-
throw MissingDepositsException.missingRange(
228-
UInt64.valueOf(depositMerkleTree.getDepositCount()), eth1DepositCount);
229-
}
230-
final DepositTree merkleTree =
231-
depositMerkleTree.getTreeAtDepositIndex(eth1DepositCount.intValue());
232226
return depositNavigableMap
233227
.subMap(fromDepositIndex, true, toDepositIndex, false)
234228
.values()
@@ -241,7 +235,9 @@ private SszList<Deposit> getDepositsWithProof(
241235
}
242236
expectedDepositIndex.set(deposit.getIndex().plus(ONE));
243237
SszBytes32Vector proof =
244-
depositProofSchema.of(merkleTree.getProof(deposit.getIndex().intValue()));
238+
depositProofSchema.of(
239+
depositMerkleTree.getProofWithViewBoundary(
240+
deposit.getIndex().intValue(), eth1DepositCount.intValue()));
245241
return new DepositWithIndex(proof, deposit.getData(), deposit.getIndex());
246242
})
247243
.collect(depositsSchema.collector());

beacon/validator/src/test/java/tech/pegasys/teku/validator/coordinator/DepositProviderTest.java

+6-11
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import static org.assertj.core.api.Assertions.assertThat;
1717
import static org.assertj.core.api.Assertions.assertThatThrownBy;
18+
import static org.mockito.ArgumentMatchers.eq;
1819
import static org.mockito.Mockito.mock;
1920
import static org.mockito.Mockito.verify;
2021
import static org.mockito.Mockito.verifyNoInteractions;
@@ -43,14 +44,13 @@
4344
import tech.pegasys.teku.spec.datastructures.operations.Deposit;
4445
import tech.pegasys.teku.spec.datastructures.operations.DepositData;
4546
import tech.pegasys.teku.spec.datastructures.operations.DepositWithIndex;
46-
import tech.pegasys.teku.spec.datastructures.state.AnchorPoint;
4747
import tech.pegasys.teku.spec.datastructures.state.Checkpoint;
4848
import tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState;
4949
import tech.pegasys.teku.spec.datastructures.util.DepositUtil;
5050
import tech.pegasys.teku.spec.datastructures.util.MerkleTree;
51+
import tech.pegasys.teku.spec.datastructures.util.OptimizedMerkleTree;
5152
import tech.pegasys.teku.spec.util.DataStructureUtil;
5253
import tech.pegasys.teku.storage.client.RecentChainData;
53-
import tech.pegasys.teku.storage.store.UpdatableStore;
5454

5555
public class DepositProviderTest {
5656

@@ -78,7 +78,8 @@ void setup(final int maxDeposits) {
7878
new DepositProvider(
7979
new StubMetricsSystem(), recentChainData, eth1DataCache, spec, eventLogger, true);
8080
depositProvider.onSyncingStatusChanged(true);
81-
depositMerkleTree = new MerkleTree(spec.getGenesisSpecConfig().getDepositContractTreeDepth());
81+
depositMerkleTree =
82+
new OptimizedMerkleTree(spec.getGenesisSpecConfig().getDepositContractTreeDepth());
8283
mockStateEth1DataVotes();
8384
createDepositEvents(40);
8485
randomEth1Data = dataStructureUtil.randomEth1Data();
@@ -152,13 +153,9 @@ void depositsWithFinalizedIndicesGetPrunedFromMap() {
152153
setup(16);
153154
Bytes32 finalizedBlockRoot = Bytes32.fromHexString("0x01");
154155
mockStateEth1DepositIndex(10);
155-
mockEth1DataDepositCount(10);
156156
mockDepositsFromEth1Block(0, 20);
157-
final AnchorPoint anchorPoint = mock(AnchorPoint.class);
158-
final UpdatableStore store = mock(UpdatableStore.class);
159-
when(recentChainData.getStore()).thenReturn(store);
160-
when(store.getLatestFinalized()).thenReturn(anchorPoint);
161-
when(anchorPoint.getState()).thenReturn(state);
157+
when(recentChainData.retrieveBlockState(eq(finalizedBlockRoot)))
158+
.thenReturn(SafeFuture.completedFuture(Optional.ofNullable(state)));
162159

163160
assertThat(depositProvider.getDepositMapSize()).isEqualTo(20);
164161

@@ -301,7 +298,6 @@ private void checkThatDepositProofIsValid(SszList<Deposit> deposits) {
301298
genesisSpec.getConfig().getDepositContractTreeDepth() + 1,
302299
((DepositWithIndex) deposit).getIndex().intValue(),
303300
depositMerkleTree.getRoot()))
304-
.withFailMessage("Expected proof to be valid but was not")
305301
.isTrue());
306302
}
307303

@@ -329,7 +325,6 @@ private void mockDepositsFromEth1Block(int startIndex, int n) {
329325
private void mockEth1DataDepositCount(int n) {
330326
Eth1Data eth1Data = mock(Eth1Data.class);
331327
when(state.getEth1Data()).thenReturn(eth1Data);
332-
when(eth1Data.getBlockHash()).thenReturn(dataStructureUtil.randomBytes32());
333328
when(eth1Data.getDepositCount()).thenReturn(UInt64.valueOf(n));
334329
}
335330

ethereum/pow/merkletree/build.gradle

-10
This file was deleted.

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

-104
This file was deleted.

0 commit comments

Comments
 (0)