13
13
14
14
package tech .pegasys .teku .validator .coordinator ;
15
15
16
- import static java .util .Collections .emptyList ;
17
16
import static tech .pegasys .teku .infrastructure .unsigned .UInt64 .ONE ;
18
17
19
18
import java .util .NavigableMap ;
28
27
import tech .pegasys .teku .ethereum .pow .api .DepositsFromBlockEvent ;
29
28
import tech .pegasys .teku .ethereum .pow .api .Eth1EventsChannel ;
30
29
import tech .pegasys .teku .ethereum .pow .api .MinGenesisTimeBlockEvent ;
31
- import tech .pegasys .teku .ethereum .pow .merkletree .DepositTree ;
32
30
import tech .pegasys .teku .infrastructure .logging .EventLogger ;
33
31
import tech .pegasys .teku .infrastructure .metrics .TekuMetricCategory ;
34
32
import tech .pegasys .teku .infrastructure .ssz .SszList ;
43
41
import tech .pegasys .teku .spec .datastructures .state .Checkpoint ;
44
42
import tech .pegasys .teku .spec .datastructures .state .beaconstate .BeaconState ;
45
43
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 ;
46
46
import tech .pegasys .teku .storage .api .FinalizedCheckpointChannel ;
47
47
import tech .pegasys .teku .storage .client .RecentChainData ;
48
48
@@ -55,7 +55,7 @@ public class DepositProvider
55
55
56
56
private final RecentChainData recentChainData ;
57
57
private final Eth1DataCache eth1DataCache ;
58
- private final DepositTree depositMerkleTree ;
58
+ private final MerkleTree depositMerkleTree ;
59
59
60
60
private final NavigableMap <UInt64 , DepositWithIndex > depositNavigableMap = new TreeMap <>();
61
61
private final Counter depositCounter ;
@@ -77,7 +77,8 @@ public DepositProvider(
77
77
this .eth1DataCache = eth1DataCache ;
78
78
this .spec = spec ;
79
79
depositUtil = new DepositUtil (spec );
80
- depositMerkleTree = new DepositTree ();
80
+ depositMerkleTree =
81
+ new OptimizedMerkleTree (spec .getGenesisSpecConfig ().getDepositContractTreeDepth ());
81
82
depositCounter =
82
83
metricsSystem .createCounter (
83
84
TekuMetricCategory .BEACON ,
@@ -97,30 +98,32 @@ public synchronized void onDepositsFromBlock(DepositsFromBlockEvent event) {
97
98
}
98
99
99
100
depositNavigableMap .put (deposit .getIndex (), deposit );
100
- depositMerkleTree .pushLeaf (deposit .getData ().hashTreeRoot ());
101
+ depositMerkleTree .add (deposit .getData ().hashTreeRoot ());
101
102
});
102
103
depositCounter .inc (event .getDeposits ().size ());
103
104
eth1DataCache .onBlockWithDeposit (
104
105
event .getBlockTimestamp (),
105
106
new Eth1Data (
106
107
depositMerkleTree .getRoot (),
107
- UInt64 .valueOf (depositMerkleTree .getDepositCount ()),
108
+ UInt64 .valueOf (depositMerkleTree .getNumberOfLeaves ()),
108
109
event .getBlockHash ()));
109
110
}
110
111
111
112
@ Override
112
113
public void onNewFinalizedCheckpoint (
113
114
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 ();
124
127
}
125
128
126
129
private synchronized void pruneDeposits (final UInt64 toIndex ) {
@@ -213,22 +216,13 @@ public synchronized int getDepositMapSize() {
213
216
* @param fromDepositIndex inclusive
214
217
* @param toDepositIndex exclusive
215
218
* @param eth1DepositCount number of deposits in the merkle tree according to Eth1Data in state
219
+ * @return
216
220
*/
217
221
private SszList <Deposit > getDepositsWithProof (
218
222
UInt64 fromDepositIndex , UInt64 toDepositIndex , UInt64 eth1DepositCount , long maxDeposits ) {
219
223
final AtomicReference <UInt64 > expectedDepositIndex = new AtomicReference <>(fromDepositIndex );
220
224
final SszListSchema <Deposit , ?> depositsSchema = depositsSchemaCache .get (maxDeposits );
221
225
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 ());
232
226
return depositNavigableMap
233
227
.subMap (fromDepositIndex , true , toDepositIndex , false )
234
228
.values ()
@@ -241,7 +235,9 @@ private SszList<Deposit> getDepositsWithProof(
241
235
}
242
236
expectedDepositIndex .set (deposit .getIndex ().plus (ONE ));
243
237
SszBytes32Vector proof =
244
- depositProofSchema .of (merkleTree .getProof (deposit .getIndex ().intValue ()));
238
+ depositProofSchema .of (
239
+ depositMerkleTree .getProofWithViewBoundary (
240
+ deposit .getIndex ().intValue (), eth1DepositCount .intValue ()));
245
241
return new DepositWithIndex (proof , deposit .getData (), deposit .getIndex ());
246
242
})
247
243
.collect (depositsSchema .collector ());
0 commit comments