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: check crosschain flags to stop inbound/outbound; get rid of outtx tracker iteration timeout #1984

Merged
merged 7 commits into from
Apr 8, 2024
2 changes: 2 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
* [1883](https://github.com/zeta-chain/node/issues/1883) - zetaclient should check 'IsSupported' flag to pause/unpause a specific chain
* [1633](https://github.com/zeta-chain/node/issues/1633) - zetaclient should be able to pick up new connector and erc20Custody addresses
* [1944](https://github.com/zeta-chain/node/pull/1944) - fix evm signer unit tests
* [1888](https://github.com/zeta-chain/node/issues/1888) - zetaclient should stop inbound/outbound txs according to cross-chain flags
* [1970](https://github.com/zeta-chain/node/issues/1970) - remove the timeout in the evm outtx tracker processing thread

### Chores

Expand Down
27 changes: 19 additions & 8 deletions zetaclient/bitcoin/bitcoin_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,10 +330,12 @@

defer ticker.Stop()
ob.logger.InTx.Info().Msgf("WatchInTx started for chain %d", ob.chain.ChainId)
sampledLogger := ob.logger.InTx.Sample(&zerolog.BasicSampler{N: 10})

Check warning on line 333 in zetaclient/bitcoin/bitcoin_client.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/bitcoin/bitcoin_client.go#L333

Added line #L333 was not covered by tests
for {
select {
case <-ticker.C():
if !ob.GetChainParams().IsSupported {
if !corecontext.IsInboundObservationEnabled(ob.coreContext, ob.GetChainParams()) {
sampledLogger.Info().Msgf("WatchInTx: inbound observation is disabled for chain %d", ob.chain.ChainId)

Check warning on line 338 in zetaclient/bitcoin/bitcoin_client.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/bitcoin/bitcoin_client.go#L337-L338

Added lines #L337 - L338 were not covered by tests
continue
}
err := ob.ObserveInTx()
Expand Down Expand Up @@ -384,12 +386,6 @@
}

func (ob *BTCChainClient) ObserveInTx() error {
// make sure inbound TXS / Send is enabled by the protocol
flags := ob.coreContext.GetCrossChainFlags()
if !flags.IsInboundEnabled {
return errors.New("inbound TXS / Send has been disabled by the protocol")
}

// get and update latest block height
cnt, err := ob.rpcClient.GetBlockCount()
if err != nil {
Expand Down Expand Up @@ -438,6 +434,9 @@
}

// add block header to zetabridge
// TODO: consider having a separate ticker(from TSS scaning) for posting block headers
// https://github.com/zeta-chain/node/issues/1847
flags := ob.coreContext.GetCrossChainFlags()

Check warning on line 439 in zetaclient/bitcoin/bitcoin_client.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/bitcoin/bitcoin_client.go#L439

Added line #L439 was not covered by tests
if flags.BlockHeaderVerificationFlags != nil && flags.BlockHeaderVerificationFlags.IsBtcTypeChainEnabled {
err = ob.postBlockHeader(bn)
if err != nil {
Expand Down Expand Up @@ -583,11 +582,20 @@

// WatchGasPrice watches Bitcoin chain for gas rate and post to zetacore
func (ob *BTCChainClient) WatchGasPrice() {
// report gas price right away as the ticker takes time to kick in
err := ob.PostGasPrice()
if err != nil {
ob.logger.GasPrice.Error().Err(err).Msgf("PostGasPrice error for chain %d", ob.chain.ChainId)

Check warning on line 588 in zetaclient/bitcoin/bitcoin_client.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/bitcoin/bitcoin_client.go#L586-L588

Added lines #L586 - L588 were not covered by tests
}

// start gas price ticker
ticker, err := clienttypes.NewDynamicTicker("Bitcoin_WatchGasPrice", ob.GetChainParams().GasPriceTicker)
if err != nil {
ob.logger.GasPrice.Error().Err(err).Msg("error creating ticker")
return
}
ob.logger.GasPrice.Info().Msgf("WatchGasPrice started for chain %d with interval %d",
ob.chain.ChainId, ob.GetChainParams().GasPriceTicker)

Check warning on line 598 in zetaclient/bitcoin/bitcoin_client.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/bitcoin/bitcoin_client.go#L597-L598

Added lines #L597 - L598 were not covered by tests

defer ticker.Stop()
for {
Expand Down Expand Up @@ -1122,10 +1130,13 @@
}

defer ticker.Stop()
ob.logger.OutTx.Info().Msgf("WatchInTx started for chain %d", ob.chain.ChainId)
sampledLogger := ob.logger.OutTx.Sample(&zerolog.BasicSampler{N: 10})

Check warning on line 1134 in zetaclient/bitcoin/bitcoin_client.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/bitcoin/bitcoin_client.go#L1133-L1134

Added lines #L1133 - L1134 were not covered by tests
for {
select {
case <-ticker.C():
if !ob.GetChainParams().IsSupported {
if !corecontext.IsOutboundObservationEnabled(ob.coreContext, ob.GetChainParams()) {
sampledLogger.Info().Msgf("WatchOutTx: outbound observation is disabled for chain %d", ob.chain.ChainId)

Check warning on line 1139 in zetaclient/bitcoin/bitcoin_client.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/bitcoin/bitcoin_client.go#L1138-L1139

Added lines #L1138 - L1139 were not covered by tests
continue
}
trackers, err := ob.zetaClient.GetAllOutTxTrackerByChain(ob.chain.ChainId, interfaces.Ascending)
Expand Down
9 changes: 0 additions & 9 deletions zetaclient/bitcoin/bitcoin_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -712,12 +712,3 @@ func TestGetBtcEventErrors(t *testing.T) {
require.Nil(t, event)
})
}

func TestBTCChainClient_ObserveInTx(t *testing.T) {
t.Run("should return error", func(t *testing.T) {
// create mainnet mock client
btcClient := MockBTCClientMainnet()
err := btcClient.ObserveInTx()
require.ErrorContains(t, err, "inbound TXS / Send has been disabled by the protocol")
})
}
3 changes: 2 additions & 1 deletion zetaclient/bitcoin/inbound_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/zeta-chain/zetacore/pkg/coin"
corecontext "github.com/zeta-chain/zetacore/zetaclient/core_context"
"github.com/zeta-chain/zetacore/zetaclient/types"
"github.com/zeta-chain/zetacore/zetaclient/zetabridge"
)
Expand All @@ -22,7 +23,7 @@
for {
select {
case <-ticker.C():
if !ob.GetChainParams().IsSupported {
if !corecontext.IsInboundObservationEnabled(ob.coreContext, ob.GetChainParams()) {

Check warning on line 26 in zetaclient/bitcoin/inbound_tracker.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/bitcoin/inbound_tracker.go#L26

Added line #L26 was not covered by tests
continue
}
err := ob.ObserveTrackerSuggestions()
Expand Down
12 changes: 12 additions & 0 deletions zetaclient/core_context/zeta_core_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,15 @@ func (c *ZetaCoreContext) Update(
c.currentTssPubkey = tssPubKey
}
}

lumtis marked this conversation as resolved.
Show resolved Hide resolved
// IsOutboundObservationEnabled returns true if the chain is supported and outbound flag is enabled
func IsOutboundObservationEnabled(c *ZetaCoreContext, chainParams observertypes.ChainParams) bool {
flags := c.GetCrossChainFlags()
return chainParams.IsSupported && flags.IsOutboundEnabled
}

// IsInboundObservationEnabled returns true if the chain is supported and inbound flag is enabled
func IsInboundObservationEnabled(c *ZetaCoreContext, chainParams observertypes.ChainParams) bool {
flags := c.GetCrossChainFlags()
return chainParams.IsSupported && flags.IsInboundEnabled
}
101 changes: 94 additions & 7 deletions zetaclient/core_context/zeta_core_context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package corecontext_test
import (
"testing"

"github.com/rs/zerolog"
"github.com/stretchr/testify/require"
"github.com/zeta-chain/zetacore/pkg/chains"
"github.com/zeta-chain/zetacore/testutil/sample"
Expand All @@ -12,6 +13,44 @@ import (
corecontext "github.com/zeta-chain/zetacore/zetaclient/core_context"
)

func assertPanic(t *testing.T, f func(), errorLog string) {
defer func() {
r := recover()
if r != nil {
require.Contains(t, r, errorLog)
}
}()
f()
}

func getTestCoreContext(
evmChain chains.Chain,
evmChainParams *observertypes.ChainParams,
ccFlags observertypes.CrosschainFlags) *corecontext.ZetaCoreContext {
// create config
cfg := config.NewConfig()
cfg.EVMChainConfigs[evmChain.ChainId] = config.EVMConfig{
Chain: evmChain,
}
// create core context
coreContext := corecontext.NewZetaCoreContext(cfg)
evmChainParamsMap := make(map[int64]*observertypes.ChainParams)
evmChainParamsMap[evmChain.ChainId] = evmChainParams

// feed chain params
coreContext.Update(
&observertypes.Keygen{},
[]chains.Chain{evmChain},
evmChainParamsMap,
nil,
"",
ccFlags,
true,
zerolog.Logger{},
)
return coreContext
}

func TestNewZetaCoreContext(t *testing.T) {
t.Run("should create new zeta core context with empty config", func(t *testing.T) {
testCfg := config.NewConfig()
Expand Down Expand Up @@ -264,12 +303,60 @@ func TestUpdateZetaCoreContext(t *testing.T) {
})
}

func assertPanic(t *testing.T, f func(), errorLog string) {
defer func() {
r := recover()
if r != nil {
require.Contains(t, r, errorLog)
func TestIsOutboundObservationEnabled(t *testing.T) {
// create test chain params and flags
evmChain := chains.EthChain()
ccFlags := *sample.CrosschainFlags()
chainParams := &observertypes.ChainParams{
ChainId: evmChain.ChainId,
IsSupported: true,
}

t.Run("should return true if chain is supported and outbound flag is enabled", func(t *testing.T) {
coreCTX := getTestCoreContext(evmChain, chainParams, ccFlags)
require.True(t, corecontext.IsOutboundObservationEnabled(coreCTX, *chainParams))
})
t.Run("should return false if chain is not supported yet", func(t *testing.T) {
paramsUnsupported := &observertypes.ChainParams{
ChainId: evmChain.ChainId,
IsSupported: false,
}
}()
f()
coreCTXUnsupported := getTestCoreContext(evmChain, paramsUnsupported, ccFlags)
require.False(t, corecontext.IsOutboundObservationEnabled(coreCTXUnsupported, *paramsUnsupported))
})
t.Run("should return false if outbound flag is disabled", func(t *testing.T) {
flagsDisabled := ccFlags
flagsDisabled.IsOutboundEnabled = false
coreCTXDisabled := getTestCoreContext(evmChain, chainParams, flagsDisabled)
require.False(t, corecontext.IsOutboundObservationEnabled(coreCTXDisabled, *chainParams))
})
}

func TestIsInboundObservationEnabled(t *testing.T) {
// create test chain params and flags
evmChain := chains.EthChain()
ccFlags := *sample.CrosschainFlags()
chainParams := &observertypes.ChainParams{
ChainId: evmChain.ChainId,
IsSupported: true,
}

t.Run("should return true if chain is supported and inbound flag is enabled", func(t *testing.T) {
coreCTX := getTestCoreContext(evmChain, chainParams, ccFlags)
require.True(t, corecontext.IsInboundObservationEnabled(coreCTX, *chainParams))
})
t.Run("should return false if chain is not supported yet", func(t *testing.T) {
paramsUnsupported := &observertypes.ChainParams{
ChainId: evmChain.ChainId,
IsSupported: false,
}
coreCTXUnsupported := getTestCoreContext(evmChain, paramsUnsupported, ccFlags)
require.False(t, corecontext.IsInboundObservationEnabled(coreCTXUnsupported, *paramsUnsupported))
})
t.Run("should return false if inbound flag is disabled", func(t *testing.T) {
flagsDisabled := ccFlags
flagsDisabled.IsInboundEnabled = false
coreCTXDisabled := getTestCoreContext(evmChain, chainParams, flagsDisabled)
require.False(t, corecontext.IsInboundObservationEnabled(coreCTXDisabled, *chainParams))
})
}
Loading
Loading