From 3cc6203d83a36a3c7daaaaaac7546e5841663625 Mon Sep 17 00:00:00 2001 From: Tomasz Slabon Date: Tue, 21 Nov 2023 16:33:29 +0100 Subject: [PATCH] Added retrieval of source and target wallets --- pkg/chain/ethereum/tbtc.go | 32 +++++++++++++ pkg/tbtc/chain.go | 24 ++++++++++ pkg/tbtc/chain_test.go | 23 +++++++++ pkg/tbtc/tbtc.go | 97 +++++++++++++++++++++++++++++++++++++- 4 files changed, 175 insertions(+), 1 deletion(-) diff --git a/pkg/chain/ethereum/tbtc.go b/pkg/chain/ethereum/tbtc.go index 7c53161c22..ae8c420747 100644 --- a/pkg/chain/ethereum/tbtc.go +++ b/pkg/chain/ethereum/tbtc.go @@ -1712,6 +1712,37 @@ func (tc *TbtcChain) GetWalletLock( return time.Unix(int64(lock.ExpiresAt), 0), cause, nil } +func (tc *TbtcChain) GetWalletParameters() ( + creationPeriod uint32, + creationMinBtcBalance uint64, + creationMaxBtcBalance uint64, + closureMinBtcBalance uint64, + maxAge uint32, + maxBtcTransfer uint64, + closingPeriod uint32, + err error, +) { + parameters, callErr := tc.bridge.WalletParameters() + if callErr != nil { + err = callErr + return + } + + creationPeriod = parameters.WalletCreationPeriod + creationMinBtcBalance = parameters.WalletCreationMinBtcBalance + creationMaxBtcBalance = parameters.WalletCreationMaxBtcBalance + closureMinBtcBalance = parameters.WalletClosureMinBtcBalance + maxAge = parameters.WalletMaxAge + maxBtcTransfer = parameters.WalletMaxBtcTransfer + closingPeriod = parameters.WalletClosingPeriod + + return +} + +func (tc *TbtcChain) GetLiveWalletsCount() (uint32, error) { + return tc.bridge.LiveWalletsCount() +} + func parseWalletActionType(value uint8) (tbtc.WalletActionType, error) { switch value { case 0: @@ -1883,6 +1914,7 @@ func (tc *TbtcChain) OnRedemptionProposalSubmitted( } func (tc *TbtcChain) OnMovingFundsCommitmentInitiated(handler func(uint64)) subscription.EventSubscription { + // TODO: Replace this function with a real trigger of moving funds commitment. ctx, cancelCtx := context.WithCancel(context.Background()) blocksChan := tc.blockCounter.WatchBlocks(ctx) diff --git a/pkg/tbtc/chain.go b/pkg/tbtc/chain.go index 84cb97ff9c..537bbf67a0 100644 --- a/pkg/tbtc/chain.go +++ b/pkg/tbtc/chain.go @@ -188,6 +188,22 @@ type BridgeChain interface { // if the wallet was not found. GetWallet(walletPublicKeyHash [20]byte) (*WalletChainData, error) + // GetWalletParameters gets the current value of parameters relevant to + // wallet. + GetWalletParameters() ( + creationPeriod uint32, + creationMinBtcBalance uint64, + creationMaxBtcBalance uint64, + closureMinBtcBalance uint64, + maxAge uint32, + maxBtcTransfer uint64, + closingPeriod uint32, + err error, + ) + + // GetLiveWalletsCount gets the current count of live wallets. + GetLiveWalletsCount() (uint32, error) + // ComputeMainUtxoHash computes the hash of the provided main UTXO // according to the on-chain Bridge rules. ComputeMainUtxoHash(mainUtxo *bitcoin.UnspentTransactionOutput) [32]byte @@ -221,6 +237,14 @@ type BridgeChain interface { fundingTxHash bitcoin.Hash, fundingOutputIndex uint32, ) (*DepositChainRequest, bool, error) + + // PastNewWalletRegisteredEvents fetches past new wallet registered 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. + PastNewWalletRegisteredEvents( + filter *NewWalletRegisteredEventFilter, + ) ([]*NewWalletRegisteredEvent, error) } // NewWalletRegisteredEvent represents a new wallet registered event. diff --git a/pkg/tbtc/chain_test.go b/pkg/tbtc/chain_test.go index 7090826d90..b2e57cf787 100644 --- a/pkg/tbtc/chain_test.go +++ b/pkg/tbtc/chain_test.go @@ -550,6 +550,12 @@ func (lc *localChain) GetDepositRequest( panic("not supported") } +func (lc *localChain) PastNewWalletRegisteredEvents( + filter *NewWalletRegisteredEventFilter, +) ([]*NewWalletRegisteredEvent, error) { + panic("not supported") +} + func (lc *localChain) setPendingRedemptionRequest( walletPublicKeyHash [20]byte, request *RedemptionRequest, @@ -647,6 +653,23 @@ func (lc *localChain) GetWalletLock(walletPublicKeyHash [20]byte) ( panic("unsupported") } +func (lc *localChain) GetWalletParameters() ( + creationPeriod uint32, + creationMinBtcBalance uint64, + creationMaxBtcBalance uint64, + closureMinBtcBalance uint64, + maxAge uint32, + maxBtcTransfer uint64, + closingPeriod uint32, + err error, +) { + panic("unsupported") +} + +func (lc *localChain) GetLiveWalletsCount() (uint32, error) { + panic("unsupported") +} + func (lc *localChain) ValidateDepositSweepProposal( proposal *DepositSweepProposal, depositsExtraInfo []struct { diff --git a/pkg/tbtc/tbtc.go b/pkg/tbtc/tbtc.go index e94d63d44b..919a93e5bf 100644 --- a/pkg/tbtc/tbtc.go +++ b/pkg/tbtc/tbtc.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "runtime" + "sort" "time" "github.com/keep-network/keep-core/pkg/bitcoin" @@ -562,8 +563,102 @@ func Initialize( }) _ = chain.OnMovingFundsCommitmentInitiated(func(blockNumber uint64) { - logger.Info("Moving funds commitment initiated at block %d", blockNumber) + go func() { + logger.Info("Moving funds commitment initiated at block %d", blockNumber) + + events, err := chain.PastNewWalletRegisteredEvents(nil) + if err != nil { + logger.Errorf( + "failed to get past new wallet registered events: [%v]", + err, + ) + return + } + + // Take the oldest first + sort.SliceStable(events, func(i, j int) bool { + return events[i].BlockNumber < events[j].BlockNumber + }) + + var walletPublicKeyHashes [][20]byte + for _, event := range events { + walletPublicKeyHashes = append( + walletPublicKeyHashes, + event.WalletPublicKeyHash, + ) + } + + movingFundsWallets := make(map[[20]byte]*WalletChainData) + liveWallets := make(map[[20]byte]*WalletChainData) + + for _, walletPublicKeyHash := range walletPublicKeyHashes { + wallet, err := chain.GetWallet(walletPublicKeyHash) + if err != nil { + logger.Errorf( + "skipping moving funds commitment for wallet with PKH "+ + "[0x%x] due to error getting wallet: [%v]", + walletPublicKeyHash, + err, + ) + continue + } + + if wallet.State == StateMovingFunds { + movingFundsWallets[walletPublicKeyHash] = wallet + } else if wallet.State == StateLive { + liveWallets[walletPublicKeyHash] = wallet + } + } + + logger.Infof( + "found [%v] wallets with state MovingFunds and [%v] wallets "+ + "with state Live [%v]", + len(movingFundsWallets), + len(liveWallets), + ) + + // TODO: Read `walletMaxBtcTransfer` and use it for target wallet + // selection. + _, _, _, _, _, _, _, _ = chain.GetWalletParameters() + + for walletPublicKeyHash, wallet := range movingFundsWallets { + walletMainUtxo, err := DetermineWalletMainUtxo( + walletPublicKeyHash, + chain, + btcChain, + ) + if err != nil { + logger.Errorf( + "skipping moving funds commitment for wallet with PKH "+ + "[0x%x] due to error determining wallet main UTXO: [%v]", + walletPublicKeyHash, + err, + ) + continue + } + + walletBalance := walletMainUtxo.Value + + // Check if the wallet meets the condition for moving funds + // commitment. + if wallet.State != StateMovingFunds || + wallet.PendingRedemptionsValue > 0 || + wallet.PendingMovedFundsSweepRequestsCount > 0 || + wallet.MovingFundsTargetWalletsCommitmentHash != [32]byte{} || + walletBalance <= 0 { + logger.Infof( + "skipping moving funds commitment for wallet with PKH "+ + "[0x%x] due to unmet conditions", + walletPublicKeyHash, + ) + continue + } + + // TODO: Continue with moving funds commitment + } + }() }) + return nil }