Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fix bitcoin fee rate and increase evm outtx inclusion timeout #1713

Merged
merged 9 commits into from
Feb 8, 2024
2 changes: 2 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
* [1690](https://github.com/zeta-chain/node/issues/1690) - double watched gas prices and fix btc scheduler
* [1687](https://github.com/zeta-chain/node/pull/1687) - only use EVM supported chains for gas stability pool
* [1692](https://github.com/zeta-chain/node/pull/1692) - fix get params query for emissions module
* [1707](https://github.com/zeta-chain/node/issues/1707) - fix bitcoin fee rate estimation
* [1712](https://github.com/zeta-chain/node/issues/1712) - increase EVM outtx inclusion timeout to 20 minutes

### Tests

Expand Down
2 changes: 1 addition & 1 deletion zetaclient/bitcoin_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ func (ob *BitcoinChainClient) PostGasPrice() error {
return nil
}
// EstimateSmartFee returns the fees per kilobyte (BTC/kb) targeting given block confirmation
feeResult, err := ob.rpcClient.EstimateSmartFee(1, &btcjson.EstimateModeConservative)
feeResult, err := ob.rpcClient.EstimateSmartFee(1, &btcjson.EstimateModeEconomical)
if err != nil {
return err
}
Expand Down
86 changes: 80 additions & 6 deletions zetaclient/bitcoin_client_test.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
//go:build btc_regtest
// +build btc_regtest

package zetaclient

import (
"encoding/hex"
"fmt"
"math/big"
"strings"
"testing"
"time"

"github.com/btcsuite/btcd/btcjson"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/rpcclient"
"github.com/ethereum/go-ethereum/crypto"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
"github.com/stretchr/testify/suite"
"github.com/zeta-chain/zetacore/common"
"github.com/zeta-chain/zetacore/zetaclient/config"
)

type BitcoinClientTestSuite struct {
Expand All @@ -35,7 +38,7 @@ func (suite *BitcoinClientTestSuite) SetupTest() {
PrivKey: privateKey,
}
//client, err := NewBitcoinClient(common.BtcTestNetChain(), nil, tss, "", nil)
client, err := NewBitcoinClient(common.BtcRegtestChain(), nil, tss, "/tmp", nil)
client, err := NewBitcoinClient(common.BtcRegtestChain(), nil, tss, "/tmp", nil, log.Logger, config.BTCConfig{}, nil)
suite.Require().NoError(err)
suite.BitcoinChainClient = client
skBytes, err := hex.DecodeString(skHex)
Expand Down Expand Up @@ -71,6 +74,20 @@ func (suite *BitcoinClientTestSuite) TearDownSuite() {

}

func getFeeRate(client *rpcclient.Client, confTarget int64, estimateMode *btcjson.EstimateSmartFeeMode) (*big.Int, error) {
feeResult, err := client.EstimateSmartFee(confTarget, estimateMode)
if err != nil {
return nil, err
}
if feeResult.Errors != nil {
return nil, errors.New(strings.Join(feeResult.Errors, ", "))
}
if feeResult.FeeRate == nil {
return nil, errors.New("fee rate is nil")
}
return new(big.Int).SetInt64(int64(*feeResult.FeeRate * 1e8)), nil
}

func (suite *BitcoinClientTestSuite) Test0() {

}
Expand Down Expand Up @@ -158,6 +175,63 @@ func (suite *BitcoinClientTestSuite) Test3() {
suite.Require().NoError(err)
suite.T().Logf("block number %d", bn)
}
func TestBitcoinChainClient(t *testing.T) {
suite.Run(t, new(BitcoinClientTestSuite))

// func TestBitcoinChainClient(t *testing.T) {
// suite.Run(t, new(BitcoinClientTestSuite))
// }

func TestBitcoinFeeRate(t *testing.T) {
// mainnet config
connCfg := &rpcclient.ConnConfig{
Host: "127.0.0.1:8332",
User: "username",
Pass: "password",
Params: "mainnet",
HTTPPostMode: true,
DisableTLS: true,
}
client, err := rpcclient.New(connCfg, nil)
ws4charlie marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
t.Error(err)
}
bn, err := client.GetBlockCount()
if err != nil {
t.Error(err)
}

// get fee rate for 1 block target
feeRateConservative1, errCon1 := getFeeRate(client, 1, &btcjson.EstimateModeConservative)
if errCon1 != nil {
t.Error(errCon1)
}
feeRateEconomical1, errEco1 := getFeeRate(client, 1, &btcjson.EstimateModeEconomical)
if errEco1 != nil {
t.Error(errEco1)
}
// get fee rate for 2 block target
feeRateConservative2, errCon2 := getFeeRate(client, 2, &btcjson.EstimateModeConservative)
if errCon2 != nil {
t.Error(errCon2)
}
feeRateEconomical2, errEco2 := getFeeRate(client, 2, &btcjson.EstimateModeEconomical)
if errEco2 != nil {
t.Error(errEco2)
}
fmt.Printf("Block: %d, Conservative-1 fee rate: %d, Economical-1 fee rate: %d\n", bn, feeRateConservative1.Uint64(), feeRateEconomical1.Uint64())
fmt.Printf("Block: %d, Conservative-2 fee rate: %d, Economical-2 fee rate: %d\n", bn, feeRateConservative2.Uint64(), feeRateEconomical2.Uint64())

// monitor fee rate every 5 minutes
for {
time.Sleep(time.Duration(5) * time.Minute)
bn, err = client.GetBlockCount()
feeRateConservative1, errCon1 = getFeeRate(client, 1, &btcjson.EstimateModeConservative)
feeRateEconomical1, errEco1 = getFeeRate(client, 1, &btcjson.EstimateModeEconomical)
feeRateConservative2, errCon2 = getFeeRate(client, 2, &btcjson.EstimateModeConservative)
feeRateEconomical2, errEco2 = getFeeRate(client, 2, &btcjson.EstimateModeEconomical)
if err != nil || errCon1 != nil || errEco1 != nil || errCon2 != nil || errEco2 != nil {
continue
}
fmt.Printf("Block: %d, Conservative-1 fee rate: %d, Economical-1 fee rate: %d\n", bn, feeRateConservative1.Uint64(), feeRateEconomical1.Uint64())
fmt.Printf("Block: %d, Conservative-2 fee rate: %d, Economical-2 fee rate: %d\n", bn, feeRateConservative2.Uint64(), feeRateEconomical2.Uint64())
}
}
2 changes: 1 addition & 1 deletion zetaclient/evm_signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (
)

const (
OutTxInclusionTimeout = 10 * time.Minute
OutTxInclusionTimeout = 20 * time.Minute
OutTxTrackerReportTimeout = 10 * time.Minute
ZetaBlockTime = 6500 * time.Millisecond
)
Expand Down
6 changes: 6 additions & 0 deletions zetaclient/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/btcsuite/btcd/btcjson"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/rpcclient"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
Expand Down Expand Up @@ -99,7 +100,12 @@ type ZetaCoreBridger interface {
// BTCRPCClient is the interface for BTC RPC client
type BTCRPCClient interface {
GetNetworkInfo() (*btcjson.GetNetworkInfoResult, error)
CreateWallet(name string, opts ...rpcclient.CreateWalletOpt) (*btcjson.CreateWalletResult, error)
GetNewAddress(account string) (btcutil.Address, error)
GenerateToAddress(numBlocks int64, address btcutil.Address, maxTries *int64) ([]*chainhash.Hash, error)
GetBalance(account string) (btcutil.Amount, error)
SendRawTransaction(tx *wire.MsgTx, allowHighFees bool) (*chainhash.Hash, error)
ListUnspent() ([]btcjson.ListUnspentResult, error)
ListUnspentMinMaxAddresses(minConf int, maxConf int, addrs []btcutil.Address) ([]btcjson.ListUnspentResult, error)
EstimateSmartFee(confTarget int64, mode *btcjson.EstimateSmartFeeMode) (*btcjson.EstimateSmartFeeResult, error)
GetTransaction(txHash *chainhash.Hash) (*btcjson.GetTransactionResult, error)
Expand Down
Loading