Skip to content

Commit

Permalink
Added wallet archiving on wallet closed event
Browse files Browse the repository at this point in the history
  • Loading branch information
tomaszslabon committed Jun 7, 2024
1 parent 4e19c4d commit accb4b1
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 3 deletions.
8 changes: 8 additions & 0 deletions pkg/tbtc/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,14 @@ type BridgeChain interface {
// according to the on-chain Bridge rules.
ComputeMainUtxoHash(mainUtxo *bitcoin.UnspentTransactionOutput) [32]byte

// 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)

// 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
Expand Down
6 changes: 6 additions & 0 deletions pkg/tbtc/chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,12 @@ func (lc *localChain) GetInactivityClaimNonce(walletID [32]byte) (*big.Int, erro
return big.NewInt(int64(nonce)), nil
}

func (lc *localChain) PastNewWalletRegisteredEvents(
filter *NewWalletRegisteredEventFilter,
) ([]*NewWalletRegisteredEvent, error) {
panic("unsupported")
}

func (lc *localChain) PastDepositRevealedEvents(
filter *DepositRevealedEventFilter,
) ([]*DepositRevealedEvent, error) {
Expand Down
28 changes: 26 additions & 2 deletions pkg/tbtc/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -1125,8 +1125,32 @@ func (n *node) handleWalletClosure(walletID [32]byte) error {
return fmt.Errorf("wallet closure not confirmed")
}

// TODO: Continue with wallet closure handling: save key material and remove
// the wallet from coordination mechanism.
events, err := n.chain.PastNewWalletRegisteredEvents(
&NewWalletRegisteredEventFilter{
EcdsaWalletID: [][32]byte{walletID},
},
)
if err != nil {
return fmt.Errorf("could not get past new wallet registered events")
}

// There should be only one event returned and the ECDSA wallet ID should
// match the requested wallet ID. These errors should never happen, but
// check just in case.
if len(events) != 1 {
return fmt.Errorf("wrong number of past new wallet registered events")
}

if events[0].EcdsaWalletID != walletID {
return fmt.Errorf("wrong past new wallet registered event returned")
}

walletPublicKeyHash := events[0].WalletPublicKeyHash

err = n.walletRegistry.archiveWallet(walletPublicKeyHash)
if err != nil {
return fmt.Errorf("failed to archive the wallet: [%v]", err)
}

return nil
}
Expand Down
52 changes: 52 additions & 0 deletions pkg/tbtc/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,45 @@ func (wr *walletRegistry) getWalletByPublicKeyHash(
return wallet{}, false
}

func (wr *walletRegistry) archiveWallet(
walletPublicKeyHash [20]byte,
) error {
wr.mutex.Lock()
defer wr.mutex.Unlock()

var walletPublicKey *ecdsa.PublicKey

for _, value := range wr.walletCache {
if value.walletPublicKeyHash == walletPublicKeyHash {
// All signers belong to one wallet. Take the wallet public key from
// the first signer.
walletPublicKey = value.signers[0].wallet.publicKey
}
}

if walletPublicKey == nil {
logger.Infof(
"node does not control wallet with public key hash [0x%x]; "+
"quitting wallet archiving",
walletPublicKeyHash,
)
return nil
}

walletStorageKey := getWalletStorageKey(walletPublicKey)

// Archive the entire wallet storage.
err := wr.walletStorage.archiveWallet(walletStorageKey)
if err != nil {
return fmt.Errorf("could not archive wallet: [%v]", err)
}

// Remove the wallet from the wallet cache.
delete(wr.walletCache, walletStorageKey)

return nil
}

// walletStorage is the component that persists data of the wallets managed
// by the given node using the underlying persistence layer. It should be
// used directly only by the walletRegistry.
Expand Down Expand Up @@ -194,6 +233,19 @@ func (ws *walletStorage) saveSigner(signer *signer) error {
return nil
}

func (ws *walletStorage) archiveWallet(walletStoragePath string) error {
err := ws.persistence.Archive(walletStoragePath)
if err != nil {
return fmt.Errorf(
"could not archive wallet storage using the "+
"underlying persistence layer: [%w]",
err,
)
}

return nil
}

// loadSigners loads all signers stored using the underlying persistence layer.
// This function should not be called from any other place than walletRegistry.
func (ws *walletStorage) loadSigners() map[string][]*signer {
Expand Down
9 changes: 8 additions & 1 deletion pkg/tbtc/tbtc.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,9 +274,16 @@ func Initialize(
event.BlockNumber,
)

node.handleWalletClosure(
err := node.handleWalletClosure(
event.WalletID,
)
if err != nil {
logger.Errorf(
"Failure while handling wallet with ID [0x%x]: [%v]",
event.WalletID,
err,
)
}
}()
})

Expand Down

0 comments on commit accb4b1

Please sign in to comment.