Skip to content
This repository has been archived by the owner on May 22, 2023. It is now read-only.

Add TBTC monitoring confirmations #592

Merged
merged 19 commits into from
Nov 12, 2020
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions pkg/chain/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ import (
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ipfs/go-log"
"github.com/keep-network/keep-common/pkg/subscription"
"github.com/keep-network/keep-core/pkg/chain"
"github.com/keep-network/keep-ecdsa/pkg/ecdsa"
)

var logger = log.Logger("keep-chain")

// Handle represents a handle to an ethereum blockchain.
type Handle interface {
// Address returns client's ethereum address.
Expand Down
32 changes: 32 additions & 0 deletions pkg/chain/confirmation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package eth

import (
"fmt"
)

// WaitForChainConfirmation ensures that after receiving specific number of block
// confirmations the state of the chain is actually as expected. It waits for
// predefined number of blocks since the start block number provided. After the
// required block number is reached it performs a check of the chain state with
// a provided function returning a boolean value.
func WaitForChainConfirmation(
pdyraga marked this conversation as resolved.
Show resolved Hide resolved
ethereumChain Handle,
startBlockNumber uint64,
blockConfirmations uint64,
stateCheck func() (bool, error),
) (bool, error) {
blockHeight := startBlockNumber + blockConfirmations
logger.Infof("waiting for block [%d] to confirm chain state", blockHeight)

err := ethereumChain.BlockCounter().WaitForBlockHeight(blockHeight)
if err != nil {
return false, fmt.Errorf("failed to wait for block height: [%v]", err)
}

result, err := stateCheck()
if err != nil {
return false, fmt.Errorf("failed to get chain state confirmation: [%v]", err)
}

return result, nil
}
17 changes: 17 additions & 0 deletions pkg/chain/ethereum/tbtc.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,23 @@ func (tec *TBTCEthereumChain) ProvideRedemptionProof(
return nil
}

// CurrentState returns the current state for the provided deposit.
func (tec *TBTCEthereumChain) CurrentState(
depositAddress string,
) (chain.DepositState, error) {
deposit, err := tec.getDepositContract(depositAddress)
if err != nil {
return 0, err
}

state, err := deposit.CurrentState()
if err != nil {
return 0, err
}

return chain.DepositState(state.Uint64()), err
}

func (tec *TBTCEthereumChain) getDepositContract(
address string,
) (*contract.Deposit, error) {
Expand Down
21 changes: 21 additions & 0 deletions pkg/chain/local/tbtc.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const (
type localDeposit struct {
keepAddress string
pubkey []byte
state chain.DepositState

utxoValue *big.Int
redemptionDigest [32]byte
Expand Down Expand Up @@ -114,6 +115,7 @@ func (tlc *TBTCLocalChain) CreateDeposit(

tlc.deposits[depositAddress] = &localDeposit{
keepAddress: keepAddress.Hex(),
state: chain.AwaitingSignerSetup,
utxoValue: big.NewInt(defaultUTXOValue),
redemptionRequestedEvents: make([]*chain.DepositRedemptionRequestedEvent, 0),
}
Expand Down Expand Up @@ -188,6 +190,7 @@ func (tlc *TBTCLocalChain) RedeemDeposit(depositAddress string) error {
return err
}

deposit.state = chain.AwaitingWithdrawalSignature
deposit.redemptionDigest = randomDigest
deposit.redemptionFee = big.NewInt(defaultInitialRedemptionFee)

Expand Down Expand Up @@ -346,6 +349,7 @@ func (tlc *TBTCLocalChain) RetrieveSignerPubkey(depositAddress string) error {
}

deposit.pubkey = keep.publicKey[:]
deposit.state = chain.AwaitingBtcFundingProof

for _, handler := range tlc.depositRegisteredPubkeyHandlers {
go func(handler func(depositAddress string), depositAddress string) {
Expand Down Expand Up @@ -387,6 +391,7 @@ func (tlc *TBTCLocalChain) ProvideRedemptionSignature(
)
}

deposit.state = chain.AwaitingWithdrawalProof
deposit.redemptionSignature = &Signature{
V: v,
R: r,
Expand Down Expand Up @@ -454,6 +459,7 @@ func (tlc *TBTCLocalChain) IncreaseRedemptionFee(
return err
}

deposit.state = chain.AwaitingWithdrawalSignature
deposit.redemptionDigest = randomDigest
deposit.redemptionFee = new(big.Int).Sub(deposit.utxoValue, newOutputValue)
deposit.redemptionSignature = nil
Expand Down Expand Up @@ -518,6 +524,7 @@ func (tlc *TBTCLocalChain) ProvideRedemptionProof(
)
}

deposit.state = chain.Redeemed
deposit.redemptionProof = &TxProof{}

for _, handler := range tlc.depositRedeemedHandlers {
Expand All @@ -529,6 +536,20 @@ func (tlc *TBTCLocalChain) ProvideRedemptionProof(
return nil
}

func (tlc *TBTCLocalChain) CurrentState(
depositAddress string,
) (chain.DepositState, error) {
tlc.tbtcLocalChainMutex.Lock()
defer tlc.tbtcLocalChainMutex.Unlock()

deposit, ok := tlc.deposits[depositAddress]
if !ok {
return 0, fmt.Errorf("no deposit with address [%v]", depositAddress)
}

return deposit.state, nil
}

func (tlc *TBTCLocalChain) DepositPubkey(
depositAddress string,
) ([]byte, error) {
Expand Down
21 changes: 21 additions & 0 deletions pkg/chain/tbtc.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ type Deposit interface {
txIndexInBlock *big.Int,
bitcoinHeaders []uint8,
) error

// CurrentState returns the current state for the provided deposit.
CurrentState(depositAddress string) (DepositState, error)
}

// TBTCSystem is an interface that provides ability to interact
Expand Down Expand Up @@ -112,3 +115,21 @@ type DepositRedemptionRequestedEvent struct {
Outpoint []byte
BlockNumber uint64
}

// DepositState represents the deposit state.
type DepositState int

const (
Start DepositState = iota
AwaitingSignerSetup
AwaitingBtcFundingProof
FailedSetup
Active
AwaitingWithdrawalSignature
AwaitingWithdrawalProof
Redeemed
CourtesyCall
FraudLiquidationInProgress
LiquidationInProgress
Liquidated
)
42 changes: 10 additions & 32 deletions pkg/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package client

import (
"context"
"fmt"
"math/big"
"sync"
"time"
Expand Down Expand Up @@ -66,9 +65,10 @@ func Initialize(
return false
}

isKeepActive, err := waitForChainConfirmation(
isKeepActive, err := eth.WaitForChainConfirmation(
ethereumChain,
currentBlock,
blockConfirmations,
func() (bool, error) {
return ethereumChain.IsActive(keepAddress)
},
Expand Down Expand Up @@ -537,9 +537,10 @@ func monitorSigningRequests(
}
defer requestedSignatures.remove(keepAddress, event.Digest)

isAwaitingSignature, err := waitForChainConfirmation(
isAwaitingSignature, err := eth.WaitForChainConfirmation(
ethereumChain,
event.BlockNumber,
blockConfirmations,
func() (bool, error) {
return ethereumChain.IsAwaitingSignature(keepAddress, event.Digest)
},
Expand Down Expand Up @@ -624,9 +625,10 @@ func checkAwaitingSignature(
return
}

isStillAwaitingSignature, err := waitForChainConfirmation(
isStillAwaitingSignature, err := eth.WaitForChainConfirmation(
ethereumChain,
startBlock,
blockConfirmations,
func() (bool, error) {
isAwaitingSignature, err := ethereumChain.IsAwaitingSignature(keepAddress, latestDigest)
if err != nil {
Expand Down Expand Up @@ -710,9 +712,10 @@ func monitorKeepClosedEvents(
event.BlockNumber,
)

isKeepActive, err := waitForChainConfirmation(
isKeepActive, err := eth.WaitForChainConfirmation(
ethereumChain,
event.BlockNumber,
blockConfirmations,
func() (bool, error) {
return ethereumChain.IsActive(keepAddress)
},
Expand Down Expand Up @@ -773,9 +776,10 @@ func monitorKeepTerminatedEvent(
event.BlockNumber,
)

isKeepActive, err := waitForChainConfirmation(
isKeepActive, err := eth.WaitForChainConfirmation(
ethereumChain,
event.BlockNumber,
blockConfirmations,
func() (bool, error) {
return ethereumChain.IsActive(keepAddress)
},
Expand Down Expand Up @@ -815,29 +819,3 @@ func monitorKeepTerminatedEvent(

logger.Info("unsubscribing from events on keep terminated")
}

// waitForChainConfirmation ensures that after receiving specific number of block
// confirmations the state of the chain is actually as expected. It waits for
// predefined number of blocks since the start block number provided. After the
// required block number is reached it performs a check of the chain state with
// a provided function returning a boolean value.
func waitForChainConfirmation(
ethereumChain eth.Handle,
startBlockNumber uint64,
stateCheck func() (bool, error),
) (bool, error) {
blockHeight := startBlockNumber + blockConfirmations
logger.Infof("waiting for block [%d] to confirm chain state", blockHeight)

err := ethereumChain.BlockCounter().WaitForBlockHeight(blockHeight)
if err != nil {
return false, fmt.Errorf("failed to wait for block height: [%v]", err)
}

result, err := stateCheck()
if err != nil {
return false, fmt.Errorf("failed to get chain state confirmation: [%v]", err)
}

return result, nil
}
3 changes: 2 additions & 1 deletion pkg/client/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,9 +286,10 @@ func monitorSignerPoolStatus(
)
}

isRegistered, err := waitForChainConfirmation(
isRegistered, err := eth.WaitForChainConfirmation(
ethereumChain,
statusCheckBlock,
blockConfirmations,
func() (bool, error) {
return ethereumChain.IsRegisteredForApplication(
application,
Expand Down
Loading