Skip to content

Commit

Permalink
rebase develop
Browse files Browse the repository at this point in the history
  • Loading branch information
kingpinXD committed Feb 13, 2024
2 parents 0cd4a12 + 165fe5d commit a33af75
Show file tree
Hide file tree
Showing 17 changed files with 40,978 additions and 93 deletions.
5 changes: 5 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

* `zetaclientd start` : 2 inputs required from stdin

### Features

* [1698](https://github.com/zeta-chain/node/issues/1698) - bitcoin dynamic depositor fee

### Docs

* [1731](https://github.com/zeta-chain/node/pull/1731) added doc for hotkey and tss key-share password prompts.
Expand Down Expand Up @@ -32,6 +36,7 @@
### Tests

* [1584](https://github.com/zeta-chain/node/pull/1584) - allow to run E2E tests on any networks
* [1753](https://github.com/zeta-chain/node/pull/1753) - fix gosec errors on usage of rand package

### CI

Expand Down
10 changes: 10 additions & 0 deletions common/bitcoin.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,13 @@ func BitcoinNetParamsFromChainID(chainID int64) (*chaincfg.Params, error) {
return nil, fmt.Errorf("no Bitcoin net params for chain ID: %d", chainID)
}
}

// IsBitcoinRegnet returns true if the chain id is for the regnet
func IsBitcoinRegnet(chainID int64) bool {
return chainID == BtcRegtestChain().ChainId
}

// IsBitcoinMainnet returns true if the chain id is for the mainnet
func IsBitcoinMainnet(chainID int64) bool {
return chainID == BtcMainnetChain().ChainId
}
6 changes: 6 additions & 0 deletions common/constant.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package common

const (
// DefaultGasPriceMultiplier is the default gas price multiplier for outbond txs
DefaultGasPriceMultiplier = 2
)
14 changes: 6 additions & 8 deletions contrib/localnet/orchestrator/smoketest/runner/bitcoin.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (sm *SmokeTestRunner) DepositBTCWithAmount(amount float64) (txHash *chainha
sm.Logger.Info(" spendableUTXOs: %d", spendableUTXOs)
sm.Logger.Info("Now sending two txs to TSS address...")

amount = amount + zetabitcoin.BtcDepositorFeeMin
amount = amount + zetabitcoin.DefaultDepositorFee
txHash, err = sm.SendToTSSFromDeployerToDeposit(sm.BTCTSSAddress, amount, utxos, sm.BtcRPCClient, sm.BTCDeployerAddress)
if err != nil {
panic(err)
Expand Down Expand Up @@ -101,12 +101,12 @@ func (sm *SmokeTestRunner) DepositBTC(testHeader bool) {
sm.Logger.Info("Now sending two txs to TSS address...")

// send two transactions to the TSS address
amount1 := 1.1 + zetabitcoin.BtcDepositorFeeMin
amount1 := 1.1 + zetabitcoin.DefaultDepositorFee
txHash1, err := sm.SendToTSSFromDeployerToDeposit(sm.BTCTSSAddress, amount1, utxos[:2], btc, sm.BTCDeployerAddress)
if err != nil {
panic(err)
}
amount2 := 0.05 + zetabitcoin.BtcDepositorFeeMin
amount2 := 0.05 + zetabitcoin.DefaultDepositorFee
txHash2, err := sm.SendToTSSFromDeployerToDeposit(sm.BTCTSSAddress, amount2, utxos[2:4], btc, sm.BTCDeployerAddress)
if err != nil {
panic(err)
Expand Down Expand Up @@ -266,16 +266,14 @@ func (sm *SmokeTestRunner) SendToTSSFromDeployerWithMemo(
panic(err)
}

btcChainID, err := common.GetBTCChainIDFromChainParams(sm.BitcoinParams)
if err != nil {
panic(err)
}
depositorFee := zetabitcoin.DefaultDepositorFee
events := zetabitcoin.FilterAndParseIncomingTx(
[]btcjson.TxRawResult{*rawtx},
0,
sm.BTCTSSAddress.EncodeAddress(),
&log.Logger,
btcChainID,
sm.BitcoinParams,
depositorFee,
)
sm.Logger.Info("bitcoin intx events:")
for _, event := range events {
Expand Down
46 changes: 30 additions & 16 deletions x/emissions/client/tests/suite.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package querytests

import (
"math/rand"
"crypto/rand"
"math/big"
"strconv"
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
ethcfg "github.com/evmos/ethermint/cmd/config"
Expand Down Expand Up @@ -52,7 +54,7 @@ func (s *CliTestSuite) SetupSuite() {
"zeta1e9fyaulgntkrnqnl0es4nyxghp3petpn2ntu3t",
}
network.SetupZetaGenesisState(s.T(), s.cfg.GenesisState, s.cfg.Codec, observerList, false)
s.ballots = RandomBallotGenerator(20, observerList)
s.ballots = RandomBallotGenerator(s.T(), 20, observerList)
network.AddObserverData(s.T(), 2, s.cfg.GenesisState, s.cfg.Codec, s.ballots)

net, err := network.New(s.T(), app.NodeDir, s.cfg)
Expand All @@ -63,30 +65,42 @@ func (s *CliTestSuite) SetupSuite() {

}

func CreateRandomVoteList(numberOfVotes int) []observerTypes.VoteType {
func CreateRandomVoteList(t *testing.T, numberOfVotes int) []observerTypes.VoteType {
voteOptions := []observerTypes.VoteType{observerTypes.VoteType_SuccessObservation, observerTypes.VoteType_FailureObservation, observerTypes.VoteType_NotYetVoted}
min := 0
max := len(voteOptions) - 1
minVoterOptions := 0
maxBoterOptions := len(voteOptions) - 1

randomVoteOptions, err := rand.Int(rand.Reader, big.NewInt(int64(maxBoterOptions-minVoterOptions)))
if err != nil {
t.Fatal(err)
}

voteList := make([]observerTypes.VoteType, numberOfVotes)
for i := 0; i < numberOfVotes; i++ {
voteList[i] = voteOptions[rand.Intn(max-min)+min] // #nosec G404
voteList[i] = voteOptions[randomVoteOptions.Int64()]
}
return voteList
}
func RandomBallotGenerator(numberOfBallots int, voterList []string) []*observerTypes.Ballot {
func RandomBallotGenerator(t *testing.T, numberOfBallots int, voterList []string) []*observerTypes.Ballot {
ballots := make([]*observerTypes.Ballot, numberOfBallots)
ballotStatus := []observerTypes.BallotStatus{observerTypes.BallotStatus_BallotFinalized_FailureObservation, observerTypes.BallotStatus_BallotFinalized_SuccessObservation}
// #nosec G404 randomness is not a security issue here
minBallotStatus := 0
maxBallotStatus := len(ballotStatus) - 1

randomBallotStatus, err := rand.Int(rand.Reader, big.NewInt(int64(maxBallotStatus-minBallotStatus)))
if err != nil {
t.Fatal(err)
}

for i := 0; i < numberOfBallots; i++ {
ballots[i] = &observerTypes.Ballot{
Index: "",
BallotIdentifier: "TestBallot" + strconv.Itoa(i),
VoterList: voterList,
Votes: CreateRandomVoteList(len(voterList)),
ObservationType: observerTypes.ObservationType_InBoundTx,
BallotThreshold: sdk.MustNewDecFromStr("0.66"),
// #nosec G404 randomness used for testing
BallotStatus: ballotStatus[i%2],
Index: "",
BallotIdentifier: "TestBallot" + strconv.Itoa(i),
VoterList: voterList,
Votes: CreateRandomVoteList(t, len(voterList)),
ObservationType: observerTypes.ObservationType_InBoundTx,
BallotThreshold: sdk.MustNewDecFromStr("0.66"),
BallotStatus: ballotStatus[randomBallotStatus.Int64()],
BallotCreationHeight: 0,
}
}
Expand Down
88 changes: 49 additions & 39 deletions zetaclient/bitcoin/bitcoin_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (

cosmosmath "cosmossdk.io/math"
"github.com/btcsuite/btcd/btcjson"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/rpcclient"
"github.com/btcsuite/btcd/wire"
Expand All @@ -36,6 +37,10 @@ import (
"gorm.io/gorm/logger"
)

const (
DynamicDepositorFeeHeight = 832000 // Bitcoin block height to switch to dynamic depositor fee
)

var _ interfaces.ChainClient = &BTCChainClient{}

type BTCLog struct {
Expand All @@ -52,6 +57,7 @@ type BTCChainClient struct {
*metricsPkg.ChainMetrics

chain common.Chain
netParams *chaincfg.Params
rpcClient interfaces.BTCRPCClient
zetaClient interfaces.ZetaCoreBridger
Tss interfaces.TSSSigner
Expand Down Expand Up @@ -141,6 +147,11 @@ func NewBitcoinClient(
}
ob.stop = make(chan struct{})
ob.chain = chain
netParams, err := common.BitcoinNetParamsFromChainID(ob.chain.ChainId)
if err != nil {
return nil, fmt.Errorf("error getting net params for chain %d: %s", ob.chain.ChainId, err)
}
ob.netParams = netParams
ob.Mu = &sync.Mutex{}
chainLogger := logger.With().Str("chain", chain.ChainName.String()).Logger()
ob.logger = BTCLog{
Expand Down Expand Up @@ -429,25 +440,33 @@ func (ob *BTCChainClient) observeInTx() error {
}
}

tssAddress := ob.Tss.BTCAddress()
// #nosec G701 always positive
inTxs := FilterAndParseIncomingTx(
res.Block.Tx,
uint64(res.Block.Height),
tssAddress,
&ob.logger.WatchInTx,
ob.chain.ChainId,
)

// post inbound vote message to zetabridge
for _, inTx := range inTxs {
msg := ob.GetInboundVoteMessageFromBtcEvent(inTx)
zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(zetabridge.PostVoteInboundGasLimit, zetabridge.PostVoteInboundExecutionGasLimit, msg)
if err != nil {
ob.logger.WatchInTx.Error().Err(err).Msgf("observeInTxBTC: error posting to zeta core for tx %s", inTx.TxHash)
return err // we have to re-scan this block next time
} else if zetaHash != "" {
ob.logger.WatchInTx.Info().Msgf("observeInTxBTC: PostVoteInbound zeta tx hash: %s inTx %s ballot %s", zetaHash, inTx.TxHash, ballot)
if len(res.Block.Tx) > 1 {
// get depositor fee
depositorFee := CalcDepositorFee(res.Block, ob.chain.ChainId, ob.netParams, ob.logger.WatchInTx)

// filter incoming txs to TSS address
tssAddress := ob.Tss.BTCAddress()
// #nosec G701 always positive
inTxs := FilterAndParseIncomingTx(
res.Block.Tx,
uint64(res.Block.Height),
tssAddress,
&ob.logger.WatchInTx,
ob.netParams,
depositorFee,
)

// post inbound vote message to zetacore
for _, inTx := range inTxs {
msg := ob.GetInboundVoteMessageFromBtcEvent(inTx)
zetaHash, ballot, err := ob.zetaClient.PostVoteInbound(zetabridge.PostVoteInboundGasLimit, zetabridge.PostVoteInboundExecutionGasLimit, msg)
if err != nil {
ob.logger.WatchInTx.Error().Err(err).Msgf("observeInTxBTC: error posting to zeta core for tx %s", inTx.TxHash)
return err // we have to re-scan this block next time
} else if zetaHash != "" {
ob.logger.WatchInTx.Info().Msgf("observeInTxBTC: PostVoteInbound zeta tx hash: %s inTx %s ballot %s fee %v",
zetaHash, inTx.TxHash, ballot, depositorFee)
}
}
}

Expand Down Expand Up @@ -636,14 +655,15 @@ func FilterAndParseIncomingTx(
blockNumber uint64,
targetAddress string,
logger *zerolog.Logger,
chainID int64,
netParams *chaincfg.Params,
depositorFee float64,
) []*BTCInTxEvnet {
inTxs := make([]*BTCInTxEvnet, 0)
for idx, tx := range txs {
if idx == 0 {
continue // the first tx is coinbase; we do not process coinbase tx
}
inTx, err := GetBtcEvent(tx, targetAddress, blockNumber, logger, chainID)
inTx, err := GetBtcEvent(tx, targetAddress, blockNumber, logger, netParams, depositorFee)
if err != nil {
logger.Error().Err(err).Msgf("FilterAndParseIncomingTx: error getting btc event for tx %s in block %d", tx.Txid, blockNumber)
continue
Expand Down Expand Up @@ -685,7 +705,8 @@ func GetBtcEvent(
targetAddress string,
blockNumber uint64,
logger *zerolog.Logger,
chainID int64,
netParams *chaincfg.Params,
depositorFee float64,
) (*BTCInTxEvnet, error) {
found := false
var value float64
Expand All @@ -699,23 +720,18 @@ func GetBtcEvent(
if err != nil {
return nil, err
}

bitcoinNetParams, err := common.BitcoinNetParamsFromChainID(chainID)
if err != nil {
return nil, fmt.Errorf("btc: error getting bitcoin net params : %v", err)
}
wpkhAddress, err := btcutil.NewAddressWitnessPubKeyHash(hash, bitcoinNetParams)
wpkhAddress, err := btcutil.NewAddressWitnessPubKeyHash(hash, netParams)
if err != nil {
return nil, err
}
if wpkhAddress.EncodeAddress() != targetAddress {
return nil, nil // irrelevant tx to us, skip
}
// deposit amount has to be no less than the minimum depositor fee
if out.Value < BtcDepositorFeeMin {
return nil, fmt.Errorf("btc deposit amount %v in txid %s is less than minimum depositor fee %v", value, tx.Txid, BtcDepositorFeeMin)
if out.Value < depositorFee {
return nil, fmt.Errorf("btc deposit amount %v in txid %s is less than depositor fee %v", value, tx.Txid, depositorFee)
}
value = out.Value - BtcDepositorFeeMin
value = out.Value - depositorFee

out = tx.Vout[1]
script = out.ScriptPubKey.Hex
Expand Down Expand Up @@ -754,13 +770,7 @@ func GetBtcEvent(
return nil, errors.Wrapf(err, "error decoding pubkey")
}
hash := btcutil.Hash160(pkBytes)

bitcoinNetParams, err := common.BitcoinNetParamsFromChainID(chainID)
if err != nil {
return nil, fmt.Errorf("btc: error getting bitcoin net params : %v", err)
}

addr, err := btcutil.NewAddressWitnessPubKeyHash(hash, bitcoinNetParams)
addr, err := btcutil.NewAddressWitnessPubKeyHash(hash, netParams)
if err != nil {
return nil, errors.Wrapf(err, "error decoding pubkey hash")
}
Expand Down Expand Up @@ -845,7 +855,7 @@ func (ob *BTCChainClient) FetchUTXOS() error {
utxosFiltered := make([]btcjson.ListUnspentResult, 0)
for _, utxo := range utxos {
// UTXOs big enough to cover the cost of spending themselves
if utxo.Amount < BtcDepositorFeeMin {
if utxo.Amount < DefaultDepositorFee {
continue
}
// we don't want to spend other people's unconfirmed UTXOs as they may not be safe to spend
Expand Down
Loading

0 comments on commit a33af75

Please sign in to comment.