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

Redemption flow actions #585

Merged
merged 34 commits into from
Nov 9, 2020
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
6d3e2da
Stub of the provide redemption signature action
lukasz-zimnoch Oct 22, 2020
2fa23da
Provide redemption signature action
lukasz-zimnoch Oct 22, 2020
f84d2b0
Merge branch 'master' into redemption-actions
lukasz-zimnoch Oct 23, 2020
43292b4
Simplify the iterator of past signature events
lukasz-zimnoch Oct 23, 2020
b13b76f
Remove the direct dependency on `gen/abi`
lukasz-zimnoch Oct 23, 2020
c120196
Add line break on start event casting
lukasz-zimnoch Oct 23, 2020
b5621ba
Implementation of the redemption proof action
lukasz-zimnoch Oct 23, 2020
230da52
Merge branch 'master' into redemption-actions
lukasz-zimnoch Oct 23, 2020
8bf4841
Set the right timeout for redemption proof action
lukasz-zimnoch Oct 23, 2020
db1536f
Move auxiliary types above `monitorAndAct`
lukasz-zimnoch Oct 26, 2020
3396b77
Change alias of the `pkg/chain` package
lukasz-zimnoch Oct 26, 2020
2307ccd
Update tbtc and use the `TBTCSystemEventLog`
lukasz-zimnoch Oct 26, 2020
4482cbd
Rename `BondedECDSAKeepFilterer`
lukasz-zimnoch Oct 26, 2020
513cc8f
Add TODO about chain reorgs
lukasz-zimnoch Oct 26, 2020
01696f3
Change signature lookup during action execution
lukasz-zimnoch Oct 26, 2020
6c03e6b
Optimize the start block when fetching past events
lukasz-zimnoch Oct 26, 2020
1c9aa09
Happy path test for provide redemption signature
lukasz-zimnoch Oct 27, 2020
1d4bcc1
Add GoSec exception for local chain randomness
lukasz-zimnoch Oct 27, 2020
073fcf0
Add remaining tests for provide signature action
lukasz-zimnoch Oct 27, 2020
5c55f3c
Happy path test for provide redemption proof
lukasz-zimnoch Oct 27, 2020
46e1780
Fix failing unit tests
lukasz-zimnoch Oct 27, 2020
fa9e034
Add remaining tests for provide proof action
lukasz-zimnoch Oct 27, 2020
a9a5a8d
Tidy the go.sum file
lukasz-zimnoch Oct 29, 2020
909ea90
Add comment to `BlockTimestamp` method
lukasz-zimnoch Oct 29, 2020
d507bf5
Add TODO about rate limiter
lukasz-zimnoch Oct 29, 2020
10f673d
Move TBTC chain interface to `pkg/chain`
lukasz-zimnoch Oct 29, 2020
2f77416
Fix import alias
lukasz-zimnoch Oct 29, 2020
2f38d37
Add discussion link to the TODOs section
lukasz-zimnoch Oct 29, 2020
c3df0ec
Remove signature submitted event lookup loop
lukasz-zimnoch Nov 9, 2020
5d17df5
Align mutex names in local chain implementations
lukasz-zimnoch Nov 9, 2020
d869e2d
Add ctx param to local chain constructor
lukasz-zimnoch Nov 9, 2020
2dca954
Add test for local `SubmitSignature` method
lukasz-zimnoch Nov 9, 2020
8cb25fd
Merge branch 'master' into redemption-actions
lukasz-zimnoch Nov 9, 2020
9f67bfa
Add comment about `IncreaseRedemptionFee` call
lukasz-zimnoch Nov 9, 2020
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
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ require (
github.com/ipfs/go-log v1.0.4
github.com/keep-network/keep-common v1.2.1-0.20201020114759-19c123cbd4f4
github.com/keep-network/keep-core v1.3.0
github.com/keep-network/tbtc v1.1.1-0.20201020115551-5f9077c74826
github.com/keep-network/tbtc v1.1.1-0.20201023121153-c4c21e8404c5
github.com/pkg/errors v0.9.1
github.com/urfave/cli v1.22.1
)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,8 @@ github.com/keep-network/keep-common v1.2.1-0.20201020114759-19c123cbd4f4 h1:Civu
github.com/keep-network/keep-common v1.2.1-0.20201020114759-19c123cbd4f4/go.mod h1:emxogTbBdey7M3jOzfxZOdfn139kN2mI2b2wA6AHKKo=
github.com/keep-network/keep-core v1.3.0 h1:7Tb33EmO/ntHOEbOiYciRlBhqu5Ln6KemWCaYK0Z6LA=
github.com/keep-network/keep-core v1.3.0/go.mod h1:1KsSSTQoN754TrFLW7kLy50pOG2CQ4BOfnJqdvEG7FA=
github.com/keep-network/tbtc v1.1.1-0.20201020115551-5f9077c74826 h1:ijlpSs+mEtur4F1DQA8450Ubuhdk4lGjIoPZr3yf7vc=
github.com/keep-network/tbtc v1.1.1-0.20201020115551-5f9077c74826/go.mod h1:igBF2MPTFkzOdZ3gcwt8h0Zb5pZaHnij/iPZoMB9IKM=
github.com/keep-network/tbtc v1.1.1-0.20201023121153-c4c21e8404c5 h1:eETyOKkTyO51URqSoXsaMe0VYB1AiQGBnlBEXX/XHOY=
github.com/keep-network/tbtc v1.1.1-0.20201023121153-c4c21e8404c5/go.mod h1:igBF2MPTFkzOdZ3gcwt8h0Zb5pZaHnij/iPZoMB9IKM=
github.com/keep-network/toml v0.3.0 h1:G+NJwWR/ZiORqeLBsDXDchYoL29PXHdxOPcCueA7ctE=
github.com/keep-network/toml v0.3.0/go.mod h1:Zeyd3lxbIlMYLREho3UK1dMP2xjqt2gLkQ5E5vM6K38=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
Expand Down
9 changes: 9 additions & 0 deletions pkg/chain/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ type Handle interface {
StakeMonitor() (chain.StakeMonitor, error)
// BlockCounter returns a block counter.
BlockCounter() chain.BlockCounter
// BlockTimestamp returns given block's timestamp.
BlockTimestamp(blockNumber *big.Int) (uint64, error)
pdyraga marked this conversation as resolved.
Show resolved Hide resolved

BondedECDSAKeepFactory
BondedECDSAKeep
Expand Down Expand Up @@ -143,4 +145,11 @@ type BondedECDSAKeep interface {

// GetOpenedTimestamp returns timestamp when the keep was created.
GetOpenedTimestamp(keepAddress common.Address) (time.Time, error)

// PastSignatureSubmittedEvents returns all signature submitted events
// for the given keep which occurred after the provided start block.
PastSignatureSubmittedEvents(
keepAddress string,
startBlock uint64,
) ([]*SignatureSubmittedEvent, error)
}
19 changes: 19 additions & 0 deletions pkg/chain/ethereum/connect.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ethereum

import (
"context"
"fmt"
"math/big"
"sync"
Expand Down Expand Up @@ -41,6 +42,7 @@ type EthereumChain struct {
blockCounter *blockcounter.EthereumBlockCounter
miningWaiter *ethutil.MiningWaiter
nonceManager *ethutil.NonceManager
blockTimestampFn blockTimestampFn

// transactionMutex allows interested parties to forcibly serialize
// transaction submission.
Expand Down Expand Up @@ -120,6 +122,7 @@ func Connect(accountKey *keystore.Key, config *ethereum.Config) (*EthereumChain,
nonceManager: nonceManager,
miningWaiter: miningWaiter,
transactionMutex: transactionMutex,
blockTimestampFn: createBlockTimestampFn(client),
}, nil
}

Expand Down Expand Up @@ -149,3 +152,19 @@ func addClientWrappers(

return loggingBackend
}

type blockTimestampFn func(blockNumber *big.Int) (uint64, error)

func createBlockTimestampFn(client *ethclient.Client) blockTimestampFn {
return func(blockNumber *big.Int) (uint64, error) {
ctx, cancelCtx := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancelCtx()

header, err := client.HeaderByNumber(ctx, blockNumber)
if err != nil {
return 0, err
}

return header.Time, nil
}
}
pdyraga marked this conversation as resolved.
Show resolved Hide resolved
44 changes: 44 additions & 0 deletions pkg/chain/ethereum/ethereum.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"math/big"
"time"

"github.com/keep-network/keep-ecdsa/pkg/chain/gen/filterer"

"github.com/ethereum/go-ethereum/common"

"github.com/ipfs/go-log"
Expand Down Expand Up @@ -507,3 +509,45 @@ func (ec *EthereumChain) GetOpenedTimestamp(keepAddress common.Address) (time.Ti

return keepOpenTime, nil
}

// PastSignatureSubmittedEvents returns all signature submitted events
// for the given keep which occurred after the provided start block.
func (ec *EthereumChain) PastSignatureSubmittedEvents(
keepAddress string,
startBlock uint64,
) ([]*eth.SignatureSubmittedEvent, error) {
if !common.IsHexAddress(keepAddress) {
return nil, fmt.Errorf("invalid keep address: [%v]", keepAddress)
}

keepContractFilterer, err := filterer.NewBondedECDSAKeepFilterer(
common.HexToAddress(keepAddress),
ec.client,
)
if err != nil {
return nil, err
}

events, err := keepContractFilterer.FilterSignatureSubmitted(startBlock, nil)
if err != nil {
return nil, err
}

result := make([]*eth.SignatureSubmittedEvent, 0)

for _, event := range events {
result = append(result, &eth.SignatureSubmittedEvent{
Digest: event.Digest,
R: event.R,
S: event.S,
RecoveryID: event.RecoveryID,
})
}

return result, nil
}

// BlockTimestamp returns given block's timestamp.
func (ec *EthereumChain) BlockTimestamp(blockNumber *big.Int) (uint64, error) {
return ec.blockTimestampFn(blockNumber)
}
199 changes: 198 additions & 1 deletion pkg/chain/ethereum/tbtc.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ package ethereum
import (
"fmt"
"math/big"
"sort"

eth "github.com/keep-network/keep-ecdsa/pkg/chain"
pdyraga marked this conversation as resolved.
Show resolved Hide resolved

"github.com/ethereum/go-ethereum/common"
"github.com/keep-network/keep-common/pkg/subscription"
"github.com/keep-network/tbtc/pkg/chain/ethereum/gen/contract"
"github.com/keep-network/tbtc/pkg/chain/ethereum/gen/filterer"
pdyraga marked this conversation as resolved.
Show resolved Hide resolved
)

// TBTCEthereumChain represents an Ethereum chain handle with
Expand All @@ -15,6 +19,7 @@ type TBTCEthereumChain struct {
*EthereumChain

tbtcSystemContract *contract.TBTCSystem
tbtcSystemFilterer *filterer.TBTCSystemFilterer
}

// WithTBTCExtension extends the Ethereum chain handle with
Expand All @@ -39,9 +44,18 @@ func WithTBTCExtension(
return nil, err
}

tbtcSystemFilterer, err := filterer.NewTBTCSystemFilterer(
common.HexToAddress(tbtcSystemContractAddress),
ethereumChain.client,
)
if err != nil {
return nil, err
}

return &TBTCEthereumChain{
EthereumChain: ethereumChain,
tbtcSystemContract: tbtcSystemContract,
tbtcSystemFilterer: tbtcSystemFilterer,
}, nil
}

Expand Down Expand Up @@ -83,10 +97,140 @@ func (tec *TBTCEthereumChain) OnDepositRegisteredPubkey(
handler(DepositContractAddress.Hex())
},
func(err error) error {
return fmt.Errorf("watch deposit created failed: [%v]", err)
return fmt.Errorf(
"watch deposit registered pubkey failed: [%v]",
err,
)
},
nil,
)
}

// OnDepositRedemptionRequested installs a callback that is invoked when an
// on-chain notification of a deposit redemption request is seen.
func (tec *TBTCEthereumChain) OnDepositRedemptionRequested(
handler func(depositAddress string),
) (subscription.EventSubscription, error) {
return tec.tbtcSystemContract.WatchRedemptionRequested(
func(
DepositContractAddress common.Address,
Requester common.Address,
Digest [32]uint8,
UtxoValue *big.Int,
RedeemerOutputScript []uint8,
RequestedFee *big.Int,
Outpoint []uint8,
blockNumber uint64,
) {
handler(DepositContractAddress.Hex())
},
func(err error) error {
return fmt.Errorf(
"watch deposit redemption requested failed: [%v]",
err,
)
},
nil,
nil,
nil,
)
}

// OnDepositGotRedemptionSignature installs a callback that is invoked when an
// on-chain notification of a deposit receiving a redemption signature is seen.
func (tec *TBTCEthereumChain) OnDepositGotRedemptionSignature(
handler func(depositAddress string),
) (subscription.EventSubscription, error) {
return tec.tbtcSystemContract.WatchGotRedemptionSignature(
func(
DepositContractAddress common.Address,
Digest [32]uint8,
R [32]uint8,
S [32]uint8,
Timestamp *big.Int,
blockNumber uint64,
) {
handler(DepositContractAddress.Hex())
},
func(err error) error {
return fmt.Errorf(
"watch deposit got redemption signature failed: [%v]",
err,
)
},
nil,
nil,
)
}

// OnDepositRedeemed installs a callback that is invoked when an
// on-chain notification of a deposit redemption is seen.
func (tec *TBTCEthereumChain) OnDepositRedeemed(
handler func(depositAddress string),
) (subscription.EventSubscription, error) {
return tec.tbtcSystemContract.WatchRedeemed(
func(
DepositContractAddress common.Address,
Txid [32]uint8,
Timestamp *big.Int,
blockNumber uint64,
) {
handler(DepositContractAddress.Hex())
},
func(err error) error {
return fmt.Errorf(
"watch deposit redeemed failed: [%v]",
err,
)
},
nil,
nil,
)
}

// PastDepositRedemptionRequestedEvents returns all redemption requested
// events for the given deposit which occurred after the provided start block.
// Returned events are sorted by the block number in the ascending order.
func (tec *TBTCEthereumChain) PastDepositRedemptionRequestedEvents(
depositAddress string,
startBlock uint64,
) ([]*eth.DepositRedemptionRequestedEvent, error) {
if !common.IsHexAddress(depositAddress) {
return nil, fmt.Errorf("incorrect deposit contract address")
}

events, err := tec.tbtcSystemFilterer.FilterRedemptionRequested(
[]common.Address{
common.HexToAddress(depositAddress),
},
startBlock,
nil,
)
if err != nil {
return nil, err
}

result := make([]*eth.DepositRedemptionRequestedEvent, 0)

for _, event := range events {
result = append(result, &eth.DepositRedemptionRequestedEvent{
DepositAddress: event.DepositContractAddress.Hex(),
RequesterAddress: event.Requester.Hex(),
Digest: event.Digest,
UtxoValue: event.UtxoValue,
RedeemerOutputScript: event.RedeemerOutputScript,
RequestedFee: event.RequestedFee,
Outpoint: event.Outpoint,
BlockNumber: event.BlockNumber,
})
}

// Make sure events are sorted by block number in ascending order.
sort.SliceStable(result, func(i, j int) bool {
return result[i].BlockNumber < result[j].BlockNumber
})

return result, nil
}

// KeepAddress returns the underlying keep address for the
Expand Down Expand Up @@ -130,6 +274,59 @@ func (tec *TBTCEthereumChain) RetrieveSignerPubkey(
return nil
}

// ProvideRedemptionSignature provides the redemption signature for the
// provided deposit.
func (tec *TBTCEthereumChain) ProvideRedemptionSignature(
depositAddress string,
v uint8,
r [32]uint8,
s [32]uint8,
) error {
deposit, err := tec.getDepositContract(depositAddress)
if err != nil {
return err
}

transaction, err := deposit.ProvideRedemptionSignature(v, r, s)
if err != nil {
return err
}

logger.Debugf(
"submitted ProvideRedemptionSignature transaction with hash: [%x]",
transaction.Hash(),
)

return nil
}

// IncreaseRedemptionFee increases the redemption fee for the provided deposit.
func (tec *TBTCEthereumChain) IncreaseRedemptionFee(
depositAddress string,
previousOutputValueBytes [8]uint8,
newOutputValueBytes [8]uint8,
) error {
deposit, err := tec.getDepositContract(depositAddress)
if err != nil {
return err
}

transaction, err := deposit.IncreaseRedemptionFee(
previousOutputValueBytes,
newOutputValueBytes,
)
if err != nil {
return err
}

logger.Debugf(
"submitted IncreaseRedemptionFee transaction with hash: [%x]",
transaction.Hash(),
)

return nil
}

func (tec *TBTCEthereumChain) getDepositContract(
address string,
) (*contract.Deposit, error) {
Expand Down
Loading