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

feat(btc): implement new btc rpc package #3349

Open
wants to merge 13 commits into
base: develop
Choose a base branch
from
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Refactor

* [3332](https://github.com/zeta-chain/node/pull/3332) - implement orchestrator V2. Move BTC observer-signer to V2
* [3349](https://github.com/zeta-chain/node/pull/3349) - implement new bitcoin rpc in zetaclient with improved performance and observability.

## v25.0.0

Expand Down
4 changes: 2 additions & 2 deletions cmd/zetaclientd/inbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import (
"github.com/zeta-chain/node/pkg/coin"
"github.com/zeta-chain/node/testutil/sample"
"github.com/zeta-chain/node/zetaclient/chains/base"
btcclient "github.com/zeta-chain/node/zetaclient/chains/bitcoin/client"
btcobserver "github.com/zeta-chain/node/zetaclient/chains/bitcoin/observer"
btcrpc "github.com/zeta-chain/node/zetaclient/chains/bitcoin/rpc"
evmobserver "github.com/zeta-chain/node/zetaclient/chains/evm/observer"
"github.com/zeta-chain/node/zetaclient/config"
zctx "github.com/zeta-chain/node/zetaclient/context"
Expand Down Expand Up @@ -162,7 +162,7 @@ func InboundGetBallot(_ *cobra.Command, args []string) error {
return fmt.Errorf("unable to find btc config")
}

rpcClient, err := btcrpc.NewRPCClient(bitcoinConfig)
rpcClient, err := btcclient.New(bitcoinConfig, chain.ID(), zerolog.Nop())
if err != nil {
return errors.Wrap(err, "unable to create rpc client")
}
Expand Down
35 changes: 19 additions & 16 deletions cmd/zetae2e/config/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,23 @@ import (
"context"
"fmt"

"github.com/btcsuite/btcd/rpcclient"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/gagliardetto/solana-go/rpc"
"github.com/rs/zerolog"
ton "github.com/tonkeeper/tongo/liteapi"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"

"github.com/zeta-chain/node/e2e/config"
"github.com/zeta-chain/node/e2e/runner"
tonrunner "github.com/zeta-chain/node/e2e/runner/ton"
"github.com/zeta-chain/node/pkg/chains"
"github.com/zeta-chain/node/pkg/retry"
zetacore_rpc "github.com/zeta-chain/node/pkg/rpc"
btcclient "github.com/zeta-chain/node/zetaclient/chains/bitcoin/client"
tonconfig "github.com/zeta-chain/node/zetaclient/chains/ton"
zetaclientconfig "github.com/zeta-chain/node/zetaclient/config"
)

// getClientsFromConfig get clients from config
Expand Down Expand Up @@ -72,27 +75,27 @@ func getClientsFromConfig(ctx context.Context, conf config.Config, account confi
}

// getBtcClient get btc client
func getBtcClient(rpcConf config.BitcoinRPC) (*rpcclient.Client, error) {
var param string
switch rpcConf.Params {
func getBtcClient(e2eConfig config.BitcoinRPC) (*btcclient.Client, error) {
cfg := zetaclientconfig.BTCConfig{
RPCUsername: e2eConfig.User,
RPCPassword: e2eConfig.Pass,
RPCHost: e2eConfig.Host,
RPCParams: string(e2eConfig.Params),
}

var chain chains.Chain
switch e2eConfig.Params {
case config.Regnet:
chain = chains.BitcoinRegtest
case config.Testnet3:
param = "testnet3"
chain = chains.BitcoinTestnet
case config.Mainnet:
param = "mainnet"
chain = chains.BitcoinMainnet
default:
return nil, fmt.Errorf("invalid bitcoin params %s", rpcConf.Params)
return nil, fmt.Errorf("invalid bitcoin params %s", e2eConfig.Params)
}

connCfg := &rpcclient.ConnConfig{
Host: rpcConf.Host,
User: rpcConf.User,
Pass: rpcConf.Pass,
HTTPPostMode: rpcConf.HTTPPostMode,
DisableTLS: rpcConf.DisableTLS,
Params: param,
}
return rpcclient.New(connCfg, nil)
return btcclient.New(cfg, chain.ChainId, zerolog.Nop())
}

// getEVMClient get evm client
Expand Down
20 changes: 8 additions & 12 deletions e2e/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,10 @@ type RPCs struct {

// BitcoinRPC contains the configuration for the Bitcoin RPC endpoint
type BitcoinRPC struct {
User string `yaml:"user"`
Pass string `yaml:"pass"`
Host string `yaml:"host"`
HTTPPostMode bool `yaml:"http_post_mode"`
DisableTLS bool `yaml:"disable_tls"`
Params BitcoinNetworkType `yaml:"params"`
User string `yaml:"user"`
Pass string `yaml:"pass"`
Host string `yaml:"host"`
Params BitcoinNetworkType `yaml:"params"`
}

// Contracts contains the addresses of predeployed contracts
Expand Down Expand Up @@ -166,12 +164,10 @@ func DefaultConfig() Config {
Zevm: "http://zetacore0:8545",
EVM: "http://eth:8545",
Bitcoin: BitcoinRPC{
Host: "bitcoin:18443",
User: "smoketest",
Pass: "123",
HTTPPostMode: true,
DisableTLS: true,
Params: Regnet,
Host: "bitcoin:18443",
User: "smoketest",
Pass: "123",
Params: Regnet,
},
ZetaCoreGRPC: "zetacore0:9090",
ZetaCoreRPC: "http://zetacore0:26657",
Expand Down
2 changes: 1 addition & 1 deletion e2e/e2etests/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func withdrawBTCZRC20(r *runner.E2ERunner, to btcutil.Address, amount *big.Int)
hash, err := chainhash.NewHashFromStr(outTxHash)
require.NoError(r, err)

rawTx, err := r.BtcRPCClient.GetRawTransactionVerbose(hash)
rawTx, err := r.BtcRPCClient.GetRawTransactionVerbose(r.Ctx, hash)
require.NoError(r, err)

r.Logger.Info("raw tx:")
Expand Down
2 changes: 1 addition & 1 deletion e2e/e2etests/test_crosschain_swap.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) {
outboundHash, err := chainhash.NewHashFromStr(cctx.GetCurrentOutboundParam().Hash)
require.NoError(r, err)

txraw, err := r.BtcRPCClient.GetRawTransactionVerbose(outboundHash)
txraw, err := r.BtcRPCClient.GetRawTransactionVerbose(r.Ctx, outboundHash)
require.NoError(r, err)

r.Logger.Info("out txid %s", txraw.Txid)
Expand Down
2 changes: 1 addition & 1 deletion e2e/runner/accounting.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func (r *E2ERunner) CheckBTCTSSBalance() error {
if err != nil {
continue
}
utxos, err := r.BtcRPCClient.ListUnspent()
utxos, err := r.BtcRPCClient.ListUnspent(r.Ctx)
if err != nil {
continue
}
Expand Down
2 changes: 1 addition & 1 deletion e2e/runner/balances.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ func (r *E2ERunner) GetBitcoinBalance() (string, error) {

// GetBitcoinBalanceByAddress get btc balance by address.
func (r *E2ERunner) GetBitcoinBalanceByAddress(address btcutil.Address) (btcutil.Amount, error) {
unspentList, err := r.BtcRPCClient.ListUnspentMinMaxAddresses(1, 9999999, []btcutil.Address{address})
unspentList, err := r.BtcRPCClient.ListUnspentMinMaxAddresses(r.Ctx, 1, 9999999, []btcutil.Address{address})
if err != nil {
return 0, errors.Wrap(err, "failed to list unspent")
}
Expand Down
19 changes: 11 additions & 8 deletions e2e/runner/bitcoin.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
func (r *E2ERunner) ListDeployerUTXOs() ([]btcjson.ListUnspentResult, error) {
// query UTXOs from node
utxos, err := r.BtcRPCClient.ListUnspentMinMaxAddresses(
r.Ctx,
1,
9999999,
[]btcutil.Address{r.BTCDeployerAddress},
Expand Down Expand Up @@ -59,6 +60,7 @@ func (r *E2ERunner) ListDeployerUTXOs() ([]btcjson.ListUnspentResult, error) {
func (r *E2ERunner) GetTop20UTXOsForTssAddress() ([]btcjson.ListUnspentResult, error) {
// query UTXOs from node
utxos, err := r.BtcRPCClient.ListUnspentMinMaxAddresses(
r.Ctx,
0,
9999999,
[]btcutil.Address{r.BTCTSSAddress},
Expand Down Expand Up @@ -256,7 +258,7 @@ func (r *E2ERunner) sendToAddrFromDeployerWithMemo(

// create raw
r.Logger.Info("ADDRESS: %s, %s", btcDeployerAddress.EncodeAddress(), to.EncodeAddress())
tx, err := btcRPC.CreateRawTransaction(inputs, amountMap, nil)
tx, err := btcRPC.CreateRawTransaction(r.Ctx, inputs, amountMap, nil)
require.NoError(r, err)

// this adds a OP_RETURN + single BYTE len prefix to the data
Expand Down Expand Up @@ -293,22 +295,23 @@ func (r *E2ERunner) sendToAddrFromDeployerWithMemo(
}
}

stx, signed, err := btcRPC.SignRawTransactionWithWallet2(tx, inputsForSign)
stx, signed, err := btcRPC.SignRawTransactionWithWallet2(r.Ctx, tx, inputsForSign)
require.NoError(r, err)
require.True(r, signed, "btc transaction is not signed")

txid, err := btcRPC.SendRawTransaction(stx, true)
txid, err := btcRPC.SendRawTransaction(r.Ctx, stx, true)
require.NoError(r, err)
r.Logger.Info("txid: %+v", txid)
_, err = r.GenerateToAddressIfLocalBitcoin(6, btcDeployerAddress)
require.NoError(r, err)
gtx, err := btcRPC.GetTransaction(txid)
gtx, err := btcRPC.GetTransaction(r.Ctx, txid)
require.NoError(r, err)
r.Logger.Info("rawtx confirmation: %d", gtx.BlockIndex)
rawtx, err := btcRPC.GetRawTransactionVerbose(txid)
rawtx, err := btcRPC.GetRawTransactionVerbose(r.Ctx, txid)
require.NoError(r, err)

events, err := btcobserver.FilterAndParseIncomingTx(
r.Ctx,
btcRPC,
[]btcjson.TxRawResult{*rawtx},
0,
Expand Down Expand Up @@ -367,7 +370,7 @@ func (r *E2ERunner) InscribeToTSSFromDeployerWithMemo(
require.NoError(r, err)

// submit the reveal transaction
txid, err := r.BtcRPCClient.SendRawTransaction(revealTx, true)
txid, err := r.BtcRPCClient.SendRawTransaction(r.Ctx, revealTx, true)
require.NoError(r, err)
r.Logger.Info("reveal txid: %s", txid.String())

Expand All @@ -394,7 +397,7 @@ func (r *E2ERunner) GenerateToAddressIfLocalBitcoin(
) ([]*chainhash.Hash, error) {
// if not local bitcoin network, do nothing
if r.IsLocalBitcoin() {
return r.BtcRPCClient.GenerateToAddress(numBlocks, address, nil)
return r.BtcRPCClient.GenerateToAddress(r.Ctx, numBlocks, address, nil)
}
return nil, nil
}
Expand All @@ -405,7 +408,7 @@ func (r *E2ERunner) QueryOutboundReceiverAndAmount(txid string) (string, int64)
require.NoError(r, err)

// query outbound raw transaction
revertTx, err := r.BtcRPCClient.GetRawTransaction(txHash)
revertTx, err := r.BtcRPCClient.GetRawTransaction(r.Ctx, txHash)
require.NoError(r, err, revertTx)
require.True(r, len(revertTx.MsgTx().TxOut) >= 2, "bitcoin outbound must have at least two outputs")

Expand Down
4 changes: 2 additions & 2 deletions e2e/runner/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"
"net/http"

"github.com/btcsuite/btcd/rpcclient"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/gagliardetto/solana-go/rpc"
Expand All @@ -13,14 +12,15 @@ import (

tonrunner "github.com/zeta-chain/node/e2e/runner/ton"
zetacore_rpc "github.com/zeta-chain/node/pkg/rpc"
btcclient "github.com/zeta-chain/node/zetaclient/chains/bitcoin/client"
)

// Clients contains all the RPC clients and gRPC clients for E2E tests
type Clients struct {
Zetacore zetacore_rpc.Clients

// the RPC clients for external chains in the localnet
BtcRPC *rpcclient.Client
BtcRPC *btcclient.Client
Solana *rpc.Client
Evm *ethclient.Client
EvmAuth *bind.TransactOpts
Expand Down
4 changes: 2 additions & 2 deletions e2e/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (

"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/rpcclient"
"github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
Expand Down Expand Up @@ -48,6 +47,7 @@ import (
fungibletypes "github.com/zeta-chain/node/x/fungible/types"
lightclienttypes "github.com/zeta-chain/node/x/lightclient/types"
observertypes "github.com/zeta-chain/node/x/observer/types"
btcclient "github.com/zeta-chain/node/zetaclient/chains/bitcoin/client"
)

type E2ERunnerOption func(*E2ERunner)
Expand Down Expand Up @@ -86,7 +86,7 @@ type E2ERunner struct {
// rpc clients
ZEVMClient *ethclient.Client
EVMClient *ethclient.Client
BtcRPCClient *rpcclient.Client
BtcRPCClient *btcclient.Client
SolanaClient *rpc.Client

// zetacored grpc clients
Expand Down
10 changes: 5 additions & 5 deletions e2e/runner/setup_bitcoin.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func (r *E2ERunner) AddTSSToNode() {
}()

// import the TSS address
err := r.BtcRPCClient.ImportAddress(r.BTCTSSAddress.EncodeAddress())
err := r.BtcRPCClient.ImportAddress(r.Ctx, r.BTCTSSAddress.EncodeAddress())
require.NoError(r, err)

// mine some blocks to get some BTC into the deployer address
Expand All @@ -38,12 +38,12 @@ func (r *E2ERunner) SetupBitcoinAccounts(createWallet bool) {
r.SetupBtcAddress(createWallet)

// import the TSS address to index TSS utxos and transactions
err := r.BtcRPCClient.ImportAddress(r.BTCTSSAddress.EncodeAddress())
err := r.BtcRPCClient.ImportAddress(r.Ctx, r.BTCTSSAddress.EncodeAddress())
require.NoError(r, err)
r.Logger.Info("⚙️ imported BTC TSSAddress: %s", r.BTCTSSAddress.EncodeAddress())

// import deployer address to index deployer utxos and transactions
err = r.BtcRPCClient.ImportAddress(r.BTCDeployerAddress.EncodeAddress())
err = r.BtcRPCClient.ImportAddress(r.Ctx, r.BTCDeployerAddress.EncodeAddress())
require.NoError(r, err)
r.Logger.Info("⚙️ imported BTCDeployerAddress: %s", r.BTCDeployerAddress.EncodeAddress())
}
Expand Down Expand Up @@ -98,12 +98,12 @@ func (r *E2ERunner) SetupBtcAddress(createWallet bool) {
require.NoError(r, err)
argsRawMsg = append(argsRawMsg, encodedArg)
}
_, err := r.BtcRPCClient.RawRequest("createwallet", argsRawMsg)
_, err := r.BtcRPCClient.RawRequest(r.Ctx, "createwallet", argsRawMsg)
if err != nil {
require.ErrorContains(r, err, "Database already exists")
}

err = r.BtcRPCClient.ImportPrivKeyRescan(privkeyWIF, r.Name, true)
err = r.BtcRPCClient.ImportPrivKeyRescan(r.Ctx, privkeyWIF, r.Name, true)
require.NoError(r, err, "failed to execute ImportPrivKeyRescan")
}
}
Loading
Loading