Skip to content

Commit

Permalink
Adjust SPV maintainer to recent changes
Browse files Browse the repository at this point in the history
  • Loading branch information
lukasz-zimnoch committed Dec 6, 2023
1 parent d34b9e8 commit f9fde70
Show file tree
Hide file tree
Showing 9 changed files with 254 additions and 105 deletions.
16 changes: 16 additions & 0 deletions pkg/maintainer/spv/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,20 @@ type Chain interface {
mainUTXO bitcoin.UnspentTransactionOutput,
walletPublicKeyHash [20]byte,
) error

// PastDepositRevealedEvents fetches past deposit reveal events according
// to the provided filter or unfiltered if the filter is nil. Returned
// events are sorted by the block number in the ascending order, i.e. the
// latest event is at the end of the slice.
PastDepositRevealedEvents(
filter *tbtc.DepositRevealedEventFilter,
) ([]*tbtc.DepositRevealedEvent, error)

// PastRedemptionRequestedEvents fetches past redemption requested events according
// to the provided filter or unfiltered if the filter is nil. Returned
// events are sorted by the block number in the ascending order, i.e. the
// latest event is at the end of the slice.
PastRedemptionRequestedEvents(
filter *tbtc.RedemptionRequestedEventFilter,
) ([]*tbtc.RedemptionRequestedEvent, error)
}
175 changes: 164 additions & 11 deletions pkg/maintainer/spv/chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"crypto/sha256"
"encoding/binary"
"encoding/hex"
"fmt"
"math/big"
"sync"
Expand Down Expand Up @@ -32,12 +33,14 @@ type submittedDepositSweepProof struct {
type localChain struct {
mutex sync.Mutex

blockCounter chain.BlockCounter
wallets map[[20]byte]*tbtc.WalletChainData
depositRequests map[[32]byte]*tbtc.DepositChainRequest
pendingRedemptionRequests map[[32]byte]*tbtc.RedemptionRequest
submittedRedemptionProofs []*submittedRedemptionProof
submittedDepositSweepProofs []*submittedDepositSweepProof
blockCounter chain.BlockCounter
wallets map[[20]byte]*tbtc.WalletChainData
depositRequests map[[32]byte]*tbtc.DepositChainRequest
pendingRedemptionRequests map[[32]byte]*tbtc.RedemptionRequest
submittedRedemptionProofs []*submittedRedemptionProof
submittedDepositSweepProofs []*submittedDepositSweepProof
pastRedemptionRequestedEvents map[[32]byte][]*tbtc.RedemptionRequestedEvent
pastDepositRevealedEvents map[[32]byte][]*tbtc.DepositRevealedEvent

txProofDifficultyFactor *big.Int
currentEpoch uint64
Expand All @@ -47,11 +50,13 @@ type localChain struct {

func newLocalChain() *localChain {
return &localChain{
wallets: make(map[[20]byte]*tbtc.WalletChainData),
depositRequests: make(map[[32]byte]*tbtc.DepositChainRequest),
pendingRedemptionRequests: make(map[[32]byte]*tbtc.RedemptionRequest),
submittedRedemptionProofs: make([]*submittedRedemptionProof, 0),
submittedDepositSweepProofs: make([]*submittedDepositSweepProof, 0),
wallets: make(map[[20]byte]*tbtc.WalletChainData),
depositRequests: make(map[[32]byte]*tbtc.DepositChainRequest),
pendingRedemptionRequests: make(map[[32]byte]*tbtc.RedemptionRequest),
submittedRedemptionProofs: make([]*submittedRedemptionProof, 0),
submittedDepositSweepProofs: make([]*submittedDepositSweepProof, 0),
pastRedemptionRequestedEvents: make(map[[32]byte][]*tbtc.RedemptionRequestedEvent),
pastDepositRevealedEvents: make(map[[32]byte][]*tbtc.DepositRevealedEvent),
}
}

Expand Down Expand Up @@ -338,6 +343,154 @@ func (lc *localChain) setCurrentAndPrevEpochDifficulty(
lc.previousEpochDifficulty = previousEpochDifficulty
}

func (lc *localChain) PastDepositRevealedEvents(
filter *tbtc.DepositRevealedEventFilter,
) ([]*tbtc.DepositRevealedEvent, error) {
lc.mutex.Lock()
defer lc.mutex.Unlock()

eventsKey, err := buildPastDepositRevealedEventsKey(filter)
if err != nil {
return nil, err
}

events, ok := lc.pastDepositRevealedEvents[eventsKey]
if !ok {
return nil, fmt.Errorf("no events for given filter")
}

return events, nil
}

func (lc *localChain) addPastDepositRevealedEvent(
filter *tbtc.DepositRevealedEventFilter,
event *tbtc.DepositRevealedEvent,
) error {
lc.mutex.Lock()
defer lc.mutex.Unlock()

eventsKey, err := buildPastDepositRevealedEventsKey(filter)
if err != nil {
return err
}

lc.pastDepositRevealedEvents[eventsKey] = append(
lc.pastDepositRevealedEvents[eventsKey],
event,
)

return nil
}

func buildPastDepositRevealedEventsKey(
filter *tbtc.DepositRevealedEventFilter,
) ([32]byte, error) {
if filter == nil {
return [32]byte{}, nil
}

var buffer bytes.Buffer

startBlock := make([]byte, 8)
binary.BigEndian.PutUint64(startBlock, filter.StartBlock)
buffer.Write(startBlock)

if filter.EndBlock != nil {
endBlock := make([]byte, 8)
binary.BigEndian.PutUint64(startBlock, *filter.EndBlock)
buffer.Write(endBlock)
}

for _, depositor := range filter.Depositor {
depositorBytes, err := hex.DecodeString(depositor.String())
if err != nil {
return [32]byte{}, err
}

buffer.Write(depositorBytes)
}

for _, walletPublicKeyHash := range filter.WalletPublicKeyHash {
buffer.Write(walletPublicKeyHash[:])
}

return sha256.Sum256(buffer.Bytes()), nil
}

func (lc *localChain) PastRedemptionRequestedEvents(
filter *tbtc.RedemptionRequestedEventFilter,
) ([]*tbtc.RedemptionRequestedEvent, error) {
lc.mutex.Lock()
defer lc.mutex.Unlock()

eventsKey, err := buildPastRedemptionRequestedEventsKey(filter)
if err != nil {
return nil, err
}

events, ok := lc.pastRedemptionRequestedEvents[eventsKey]
if !ok {
return nil, fmt.Errorf("no events for given filter")
}

return events, nil
}

func (lc *localChain) addPastRedemptionRequestedEvent(
filter *tbtc.RedemptionRequestedEventFilter,
event *tbtc.RedemptionRequestedEvent,
) error {
lc.mutex.Lock()
defer lc.mutex.Unlock()

eventsKey, err := buildPastRedemptionRequestedEventsKey(filter)
if err != nil {
return err
}

lc.pastRedemptionRequestedEvents[eventsKey] = append(
lc.pastRedemptionRequestedEvents[eventsKey],
event,
)

return nil
}

func buildPastRedemptionRequestedEventsKey(
filter *tbtc.RedemptionRequestedEventFilter,
) ([32]byte, error) {
if filter == nil {
return [32]byte{}, nil
}

var buffer bytes.Buffer

startBlock := make([]byte, 8)
binary.BigEndian.PutUint64(startBlock, filter.StartBlock)
buffer.Write(startBlock)

if filter.EndBlock != nil {
endBlock := make([]byte, 8)
binary.BigEndian.PutUint64(startBlock, *filter.EndBlock)
buffer.Write(endBlock)
}

for _, walletPublicKeyHash := range filter.WalletPublicKeyHash {
buffer.Write(walletPublicKeyHash[:])
}

for _, redeemer := range filter.Redeemer {
redeemerHex, err := hex.DecodeString(redeemer.String())
if err != nil {
return [32]byte{}, err
}

buffer.Write(redeemerHex)
}

return sha256.Sum256(buffer.Bytes()), nil
}

type mockBlockCounter struct {
mutex sync.Mutex
currentBlock uint64
Expand Down
8 changes: 4 additions & 4 deletions pkg/maintainer/spv/deposit_sweep.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,9 @@ func getUnprovenDepositSweepTransactions(
// searched for.
startBlock := currentBlock - historyDepth

depositSweepProposals, err :=
spvChain.PastDepositSweepProposalSubmittedEvents(
&tbtc.DepositSweepProposalSubmittedEventFilter{
events, err :=
spvChain.PastDepositRevealedEvents(
&tbtc.DepositRevealedEventFilter{
StartBlock: startBlock,
},
)
Expand All @@ -261,7 +261,7 @@ func getUnprovenDepositSweepTransactions(
// There will often be multiple events emitted for a single wallet. Prepare
// a list of unique wallet public key hashes.
walletPublicKeyHashes := uniqueWalletPublicKeyHashes(
depositSweepProposals,
events,
)

unprovenDepositSweepTransactions := []*bitcoin.Transaction{}
Expand Down
40 changes: 16 additions & 24 deletions pkg/maintainer/spv/deposit_sweep_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,43 +313,35 @@ func TestGetUnprovenDepositSweepTransactions(t *testing.T) {
},
)

// Add proposal events for the wallets. Only wallet public key hash field
// Add deposit events for the wallets. Only wallet public key hash field
// is relevant as those events are just used to get a list of distinct
// wallets who performed deposit sweeps recently. The block number field
// is just to make them distinguishable while reading.
proposalEvents := []*tbtc.DepositSweepProposalSubmittedEvent{
// wallets who likely performed deposit sweeps recently. The block number
// field is just to make them distinguishable while reading.
events := []*tbtc.DepositRevealedEvent{
{
Proposal: &tbtc.DepositSweepProposal{
WalletPublicKeyHash: wallets[0].walletPublicKeyHash,
},
BlockNumber: 100,
WalletPublicKeyHash: wallets[0].walletPublicKeyHash,
BlockNumber: 100,
},
{
Proposal: &tbtc.DepositSweepProposal{
WalletPublicKeyHash: wallets[0].walletPublicKeyHash,
},
BlockNumber: 200,
WalletPublicKeyHash: wallets[0].walletPublicKeyHash,
BlockNumber: 200,
},
{
Proposal: &tbtc.DepositSweepProposal{
WalletPublicKeyHash: wallets[1].walletPublicKeyHash,
},
BlockNumber: 300,
WalletPublicKeyHash: wallets[1].walletPublicKeyHash,
BlockNumber: 300,
},
{
Proposal: &tbtc.DepositSweepProposal{
WalletPublicKeyHash: wallets[1].walletPublicKeyHash,
},
BlockNumber: 400,
WalletPublicKeyHash: wallets[1].walletPublicKeyHash,
BlockNumber: 400,
},
}

for _, proposalEvent := range proposalEvents {
err := spvChain.AddPastDepositSweepProposalSubmittedEvent(
&tbtc.DepositSweepProposalSubmittedEventFilter{
for _, event := range events {
err := spvChain.addPastDepositRevealedEvent(
&tbtc.DepositRevealedEventFilter{
StartBlock: currentBlock - historyDepth,
},
proposalEvent,
event,
)
if err != nil {
t.Fatal(err)
Expand Down
8 changes: 4 additions & 4 deletions pkg/maintainer/spv/redemptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,9 @@ func getUnprovenRedemptionTransactions(
// searched for.
startBlock := currentBlock - historyDepth

redemptionProposals, err :=
spvChain.PastRedemptionProposalSubmittedEvents(
&tbtc.RedemptionProposalSubmittedEventFilter{
events, err :=
spvChain.PastRedemptionRequestedEvents(
&tbtc.RedemptionRequestedEventFilter{
StartBlock: startBlock,
},
)
Expand All @@ -162,7 +162,7 @@ func getUnprovenRedemptionTransactions(
// There will often be multiple events emitted for a single wallet. Prepare
// a list of unique wallet public key hashes.
walletPublicKeyHashes := uniqueWalletPublicKeyHashes(
redemptionProposals,
events,
)

var unprovenRedemptionTransactions []*bitcoin.Transaction
Expand Down
38 changes: 15 additions & 23 deletions pkg/maintainer/spv/redemptions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,43 +252,35 @@ func TestGetUnprovenRedemptionTransactions(t *testing.T) {
)
}

// Add proposal events for the wallets. Only wallet public key hash field
// Add redemption events for the wallets. Only wallet public key hash field
// is relevant as those events are just used to get a list of distinct
// wallets who performed redemptions recently. The block number field
// wallets who likely performed redemptions recently. The block number field
// is just to make them distinguishable while reading.
proposalEvents := []*tbtc.RedemptionProposalSubmittedEvent{
events := []*tbtc.RedemptionRequestedEvent{
{
Proposal: &tbtc.RedemptionProposal{
WalletPublicKeyHash: wallets[0].walletPublicKeyHash,
},
BlockNumber: 100,
WalletPublicKeyHash: wallets[0].walletPublicKeyHash,
BlockNumber: 100,
},
{
Proposal: &tbtc.RedemptionProposal{
WalletPublicKeyHash: wallets[0].walletPublicKeyHash,
},
BlockNumber: 200,
WalletPublicKeyHash: wallets[0].walletPublicKeyHash,
BlockNumber: 200,
},
{
Proposal: &tbtc.RedemptionProposal{
WalletPublicKeyHash: wallets[1].walletPublicKeyHash,
},
BlockNumber: 300,
WalletPublicKeyHash: wallets[1].walletPublicKeyHash,
BlockNumber: 300,
},
{
Proposal: &tbtc.RedemptionProposal{
WalletPublicKeyHash: wallets[1].walletPublicKeyHash,
},
BlockNumber: 400,
WalletPublicKeyHash: wallets[1].walletPublicKeyHash,
BlockNumber: 400,
},
}

for _, proposalEvent := range proposalEvents {
err := spvChain.AddPastRedemptionProposalSubmittedEvent(
&tbtc.RedemptionProposalSubmittedEventFilter{
for _, event := range events {
err := spvChain.addPastRedemptionRequestedEvent(
&tbtc.RedemptionRequestedEventFilter{
StartBlock: currentBlock - historyDepth,
},
proposalEvent,
event,
)
if err != nil {
t.Fatal(err)
Expand Down
Loading

0 comments on commit f9fde70

Please sign in to comment.