Skip to content

Commit 19bc96b

Browse files
Adjust SPV maintainer to recent changes
1 parent d34b9e8 commit 19bc96b

File tree

11 files changed

+268
-122
lines changed

11 files changed

+268
-122
lines changed

cmd/flags.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,8 +337,7 @@ func initMaintainerFlags(command *cobra.Command, cfg *config.Config) {
337337
&cfg.Maintainer.Spv.HistoryDepth,
338338
"spv.historyDepth",
339339
spv.DefaultHistoryDepth,
340-
"Number of blocks to look back for past deposit sweep proposal "+
341-
"submitted events.",
340+
"Number of blocks to look back for past wallet-related events.",
342341
)
343342

344343
command.Flags().IntVar(

pkg/maintainer/spv/chain.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,20 @@ type Chain interface {
6565
mainUTXO bitcoin.UnspentTransactionOutput,
6666
walletPublicKeyHash [20]byte,
6767
) error
68+
69+
// PastDepositRevealedEvents fetches past deposit reveal events according
70+
// to the provided filter or unfiltered if the filter is nil. Returned
71+
// events are sorted by the block number in the ascending order, i.e. the
72+
// latest event is at the end of the slice.
73+
PastDepositRevealedEvents(
74+
filter *tbtc.DepositRevealedEventFilter,
75+
) ([]*tbtc.DepositRevealedEvent, error)
76+
77+
// PastRedemptionRequestedEvents fetches past redemption requested events according
78+
// to the provided filter or unfiltered if the filter is nil. Returned
79+
// events are sorted by the block number in the ascending order, i.e. the
80+
// latest event is at the end of the slice.
81+
PastRedemptionRequestedEvents(
82+
filter *tbtc.RedemptionRequestedEventFilter,
83+
) ([]*tbtc.RedemptionRequestedEvent, error)
6884
}

pkg/maintainer/spv/chain_test.go

Lines changed: 164 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"context"
66
"crypto/sha256"
77
"encoding/binary"
8+
"encoding/hex"
89
"fmt"
910
"math/big"
1011
"sync"
@@ -32,12 +33,14 @@ type submittedDepositSweepProof struct {
3233
type localChain struct {
3334
mutex sync.Mutex
3435

35-
blockCounter chain.BlockCounter
36-
wallets map[[20]byte]*tbtc.WalletChainData
37-
depositRequests map[[32]byte]*tbtc.DepositChainRequest
38-
pendingRedemptionRequests map[[32]byte]*tbtc.RedemptionRequest
39-
submittedRedemptionProofs []*submittedRedemptionProof
40-
submittedDepositSweepProofs []*submittedDepositSweepProof
36+
blockCounter chain.BlockCounter
37+
wallets map[[20]byte]*tbtc.WalletChainData
38+
depositRequests map[[32]byte]*tbtc.DepositChainRequest
39+
pendingRedemptionRequests map[[32]byte]*tbtc.RedemptionRequest
40+
submittedRedemptionProofs []*submittedRedemptionProof
41+
submittedDepositSweepProofs []*submittedDepositSweepProof
42+
pastRedemptionRequestedEvents map[[32]byte][]*tbtc.RedemptionRequestedEvent
43+
pastDepositRevealedEvents map[[32]byte][]*tbtc.DepositRevealedEvent
4144

4245
txProofDifficultyFactor *big.Int
4346
currentEpoch uint64
@@ -47,11 +50,13 @@ type localChain struct {
4750

4851
func newLocalChain() *localChain {
4952
return &localChain{
50-
wallets: make(map[[20]byte]*tbtc.WalletChainData),
51-
depositRequests: make(map[[32]byte]*tbtc.DepositChainRequest),
52-
pendingRedemptionRequests: make(map[[32]byte]*tbtc.RedemptionRequest),
53-
submittedRedemptionProofs: make([]*submittedRedemptionProof, 0),
54-
submittedDepositSweepProofs: make([]*submittedDepositSweepProof, 0),
53+
wallets: make(map[[20]byte]*tbtc.WalletChainData),
54+
depositRequests: make(map[[32]byte]*tbtc.DepositChainRequest),
55+
pendingRedemptionRequests: make(map[[32]byte]*tbtc.RedemptionRequest),
56+
submittedRedemptionProofs: make([]*submittedRedemptionProof, 0),
57+
submittedDepositSweepProofs: make([]*submittedDepositSweepProof, 0),
58+
pastRedemptionRequestedEvents: make(map[[32]byte][]*tbtc.RedemptionRequestedEvent),
59+
pastDepositRevealedEvents: make(map[[32]byte][]*tbtc.DepositRevealedEvent),
5560
}
5661
}
5762

@@ -338,6 +343,154 @@ func (lc *localChain) setCurrentAndPrevEpochDifficulty(
338343
lc.previousEpochDifficulty = previousEpochDifficulty
339344
}
340345

346+
func (lc *localChain) PastDepositRevealedEvents(
347+
filter *tbtc.DepositRevealedEventFilter,
348+
) ([]*tbtc.DepositRevealedEvent, error) {
349+
lc.mutex.Lock()
350+
defer lc.mutex.Unlock()
351+
352+
eventsKey, err := buildPastDepositRevealedEventsKey(filter)
353+
if err != nil {
354+
return nil, err
355+
}
356+
357+
events, ok := lc.pastDepositRevealedEvents[eventsKey]
358+
if !ok {
359+
return nil, fmt.Errorf("no events for given filter")
360+
}
361+
362+
return events, nil
363+
}
364+
365+
func (lc *localChain) addPastDepositRevealedEvent(
366+
filter *tbtc.DepositRevealedEventFilter,
367+
event *tbtc.DepositRevealedEvent,
368+
) error {
369+
lc.mutex.Lock()
370+
defer lc.mutex.Unlock()
371+
372+
eventsKey, err := buildPastDepositRevealedEventsKey(filter)
373+
if err != nil {
374+
return err
375+
}
376+
377+
lc.pastDepositRevealedEvents[eventsKey] = append(
378+
lc.pastDepositRevealedEvents[eventsKey],
379+
event,
380+
)
381+
382+
return nil
383+
}
384+
385+
func buildPastDepositRevealedEventsKey(
386+
filter *tbtc.DepositRevealedEventFilter,
387+
) ([32]byte, error) {
388+
if filter == nil {
389+
return [32]byte{}, nil
390+
}
391+
392+
var buffer bytes.Buffer
393+
394+
startBlock := make([]byte, 8)
395+
binary.BigEndian.PutUint64(startBlock, filter.StartBlock)
396+
buffer.Write(startBlock)
397+
398+
if filter.EndBlock != nil {
399+
endBlock := make([]byte, 8)
400+
binary.BigEndian.PutUint64(startBlock, *filter.EndBlock)
401+
buffer.Write(endBlock)
402+
}
403+
404+
for _, depositor := range filter.Depositor {
405+
depositorBytes, err := hex.DecodeString(depositor.String())
406+
if err != nil {
407+
return [32]byte{}, err
408+
}
409+
410+
buffer.Write(depositorBytes)
411+
}
412+
413+
for _, walletPublicKeyHash := range filter.WalletPublicKeyHash {
414+
buffer.Write(walletPublicKeyHash[:])
415+
}
416+
417+
return sha256.Sum256(buffer.Bytes()), nil
418+
}
419+
420+
func (lc *localChain) PastRedemptionRequestedEvents(
421+
filter *tbtc.RedemptionRequestedEventFilter,
422+
) ([]*tbtc.RedemptionRequestedEvent, error) {
423+
lc.mutex.Lock()
424+
defer lc.mutex.Unlock()
425+
426+
eventsKey, err := buildPastRedemptionRequestedEventsKey(filter)
427+
if err != nil {
428+
return nil, err
429+
}
430+
431+
events, ok := lc.pastRedemptionRequestedEvents[eventsKey]
432+
if !ok {
433+
return nil, fmt.Errorf("no events for given filter")
434+
}
435+
436+
return events, nil
437+
}
438+
439+
func (lc *localChain) addPastRedemptionRequestedEvent(
440+
filter *tbtc.RedemptionRequestedEventFilter,
441+
event *tbtc.RedemptionRequestedEvent,
442+
) error {
443+
lc.mutex.Lock()
444+
defer lc.mutex.Unlock()
445+
446+
eventsKey, err := buildPastRedemptionRequestedEventsKey(filter)
447+
if err != nil {
448+
return err
449+
}
450+
451+
lc.pastRedemptionRequestedEvents[eventsKey] = append(
452+
lc.pastRedemptionRequestedEvents[eventsKey],
453+
event,
454+
)
455+
456+
return nil
457+
}
458+
459+
func buildPastRedemptionRequestedEventsKey(
460+
filter *tbtc.RedemptionRequestedEventFilter,
461+
) ([32]byte, error) {
462+
if filter == nil {
463+
return [32]byte{}, nil
464+
}
465+
466+
var buffer bytes.Buffer
467+
468+
startBlock := make([]byte, 8)
469+
binary.BigEndian.PutUint64(startBlock, filter.StartBlock)
470+
buffer.Write(startBlock)
471+
472+
if filter.EndBlock != nil {
473+
endBlock := make([]byte, 8)
474+
binary.BigEndian.PutUint64(startBlock, *filter.EndBlock)
475+
buffer.Write(endBlock)
476+
}
477+
478+
for _, walletPublicKeyHash := range filter.WalletPublicKeyHash {
479+
buffer.Write(walletPublicKeyHash[:])
480+
}
481+
482+
for _, redeemer := range filter.Redeemer {
483+
redeemerHex, err := hex.DecodeString(redeemer.String())
484+
if err != nil {
485+
return [32]byte{}, err
486+
}
487+
488+
buffer.Write(redeemerHex)
489+
}
490+
491+
return sha256.Sum256(buffer.Bytes()), nil
492+
}
493+
341494
type mockBlockCounter struct {
342495
mutex sync.Mutex
343496
currentBlock uint64

pkg/maintainer/spv/config.go

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
const (
88
// DefaultHistoryDepth is the default value for history depth which is the
99
// number of blocks to look back from the current block when searching for
10-
// past proposal submission events. The value is the approximate number of
10+
// past wallet-related events. The value is the approximate number of
1111
// Ethereum blocks in a week, assuming one block is 12s.
1212
DefaultHistoryDepth = 50400
1313

@@ -35,22 +35,20 @@ type Config struct {
3535
Enabled bool
3636

3737
// HistoryDepth is the number of blocks to look back from the current block
38-
// when searching for past proposal submission events.
39-
// To find Bitcoin transactions for which the SPV proof should be submitted,
40-
// the maintainer first inspects the proposal events from the wallet
41-
// coordinator contract. This depth determines how far into the past the
42-
// system will consider events for processing. This value must not be too
43-
// high so that the event lookup is efficient. At the same time, this value
44-
// can not be too low to make sure all performed and not yet proven
45-
// transactions can be found.
38+
// when searching for past wallet-related events. To find Bitcoin transactions
39+
// for which the SPV proof should be submitted, the maintainer first inspects
40+
// the appropriate type of wallet-related events. This depth determines how
41+
// far into the past the system will consider events for processing. This
42+
// value must not be too high so that the event lookup is efficient. At the
43+
// same time, this value can not be too low to make sure all performed and
44+
// not yet proven transactions can be found.
4645
HistoryDepth uint64
4746

4847
// TransactionLimit sets the maximum number of confirmed transactions
4948
// returned when getting transactions for a public key hash. Once the
50-
// maintainer establishes the list of proposals of given type, based on the
51-
// proposal submission events from the wallet coordinator contract, it needs
52-
// to check Bitcoin transactions executed by the wallet. Then, it tries to
53-
// find the transactions matching the given proposal type. For example, if set
49+
// maintainer establishes the list of wallets, it needs to check Bitcoin
50+
// transactions executed by each wallet. Then, it tries to find the
51+
// transactions matching the given proposal type. For example, if set
5452
// to `20`, only the latest twenty transactions will be returned. This
5553
// value must not be too high so that the transaction lookup is efficient.
5654
// At the same time, this value can not be too low to make sure the

pkg/maintainer/spv/deposit_sweep.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -245,23 +245,23 @@ func getUnprovenDepositSweepTransactions(
245245
// searched for.
246246
startBlock := currentBlock - historyDepth
247247

248-
depositSweepProposals, err :=
249-
spvChain.PastDepositSweepProposalSubmittedEvents(
250-
&tbtc.DepositSweepProposalSubmittedEventFilter{
248+
events, err :=
249+
spvChain.PastDepositRevealedEvents(
250+
&tbtc.DepositRevealedEventFilter{
251251
StartBlock: startBlock,
252252
},
253253
)
254254
if err != nil {
255255
return nil, fmt.Errorf(
256-
"failed to get past deposit sweep proposal submitted events: [%v]",
256+
"failed to get past deposit revealed events: [%v]",
257257
err,
258258
)
259259
}
260260

261261
// There will often be multiple events emitted for a single wallet. Prepare
262262
// a list of unique wallet public key hashes.
263263
walletPublicKeyHashes := uniqueWalletPublicKeyHashes(
264-
depositSweepProposals,
264+
events,
265265
)
266266

267267
unprovenDepositSweepTransactions := []*bitcoin.Transaction{}

pkg/maintainer/spv/deposit_sweep_test.go

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -313,43 +313,35 @@ func TestGetUnprovenDepositSweepTransactions(t *testing.T) {
313313
},
314314
)
315315

316-
// Add proposal events for the wallets. Only wallet public key hash field
316+
// Add deposit events for the wallets. Only wallet public key hash field
317317
// is relevant as those events are just used to get a list of distinct
318-
// wallets who performed deposit sweeps recently. The block number field
319-
// is just to make them distinguishable while reading.
320-
proposalEvents := []*tbtc.DepositSweepProposalSubmittedEvent{
318+
// wallets who likely performed deposit sweeps recently. The block number
319+
// field is just to make them distinguishable while reading.
320+
events := []*tbtc.DepositRevealedEvent{
321321
{
322-
Proposal: &tbtc.DepositSweepProposal{
323-
WalletPublicKeyHash: wallets[0].walletPublicKeyHash,
324-
},
325-
BlockNumber: 100,
322+
WalletPublicKeyHash: wallets[0].walletPublicKeyHash,
323+
BlockNumber: 100,
326324
},
327325
{
328-
Proposal: &tbtc.DepositSweepProposal{
329-
WalletPublicKeyHash: wallets[0].walletPublicKeyHash,
330-
},
331-
BlockNumber: 200,
326+
WalletPublicKeyHash: wallets[0].walletPublicKeyHash,
327+
BlockNumber: 200,
332328
},
333329
{
334-
Proposal: &tbtc.DepositSweepProposal{
335-
WalletPublicKeyHash: wallets[1].walletPublicKeyHash,
336-
},
337-
BlockNumber: 300,
330+
WalletPublicKeyHash: wallets[1].walletPublicKeyHash,
331+
BlockNumber: 300,
338332
},
339333
{
340-
Proposal: &tbtc.DepositSweepProposal{
341-
WalletPublicKeyHash: wallets[1].walletPublicKeyHash,
342-
},
343-
BlockNumber: 400,
334+
WalletPublicKeyHash: wallets[1].walletPublicKeyHash,
335+
BlockNumber: 400,
344336
},
345337
}
346338

347-
for _, proposalEvent := range proposalEvents {
348-
err := spvChain.AddPastDepositSweepProposalSubmittedEvent(
349-
&tbtc.DepositSweepProposalSubmittedEventFilter{
339+
for _, event := range events {
340+
err := spvChain.addPastDepositRevealedEvent(
341+
&tbtc.DepositRevealedEventFilter{
350342
StartBlock: currentBlock - historyDepth,
351343
},
352-
proposalEvent,
344+
event,
353345
)
354346
if err != nil {
355347
t.Fatal(err)

pkg/maintainer/spv/redemptions.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,23 +146,23 @@ func getUnprovenRedemptionTransactions(
146146
// searched for.
147147
startBlock := currentBlock - historyDepth
148148

149-
redemptionProposals, err :=
150-
spvChain.PastRedemptionProposalSubmittedEvents(
151-
&tbtc.RedemptionProposalSubmittedEventFilter{
149+
events, err :=
150+
spvChain.PastRedemptionRequestedEvents(
151+
&tbtc.RedemptionRequestedEventFilter{
152152
StartBlock: startBlock,
153153
},
154154
)
155155
if err != nil {
156156
return nil, fmt.Errorf(
157-
"failed to get past redemption proposal submitted events: [%v]",
157+
"failed to get past redemption requested events: [%v]",
158158
err,
159159
)
160160
}
161161

162162
// There will often be multiple events emitted for a single wallet. Prepare
163163
// a list of unique wallet public key hashes.
164164
walletPublicKeyHashes := uniqueWalletPublicKeyHashes(
165-
redemptionProposals,
165+
events,
166166
)
167167

168168
var unprovenRedemptionTransactions []*bitcoin.Transaction

0 commit comments

Comments
 (0)