From 1ffab806f03b3933efe6b402d45b838b97895b8b Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 5 Jun 2024 13:39:42 +0200 Subject: [PATCH 01/16] bitcoin --- zetaclient/authz/authz_signer.go | 6 ++ zetaclient/authz/authz_signer_test.go | 2 + zetaclient/chains/bitcoin/observer/inbound.go | 6 +- .../chains/bitcoin/observer/observer.go | 78 +++++++++++++++---- .../chains/bitcoin/observer/outbound.go | 3 + zetaclient/chains/bitcoin/signer/signer.go | 24 ++++-- zetaclient/chains/bitcoin/utils.go | 3 + 7 files changed, 101 insertions(+), 21 deletions(-) diff --git a/zetaclient/authz/authz_signer.go b/zetaclient/authz/authz_signer.go index 5f1221f9a9..378573bd17 100644 --- a/zetaclient/authz/authz_signer.go +++ b/zetaclient/authz/authz_signer.go @@ -7,18 +7,22 @@ import ( crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" ) +// Signer represents a signer for a grantee key type Signer struct { KeyType authz.KeyType GranterAddress string GranteeAddress sdk.AccAddress } +// String returns a string representation of a Signer func (a Signer) String() string { return a.KeyType.String() + " " + a.GranterAddress + " " + a.GranteeAddress.String() } +// signers is a map of all the signers for the different tx types var signers map[string]Signer +// init initializes the signers map with all the crosschain tx types using the ZetaClientGranteeKey func init() { signersList := make(map[string]Signer) for _, tx := range crosschaintypes.GetAllAuthzZetaclientTxTypes() { @@ -27,6 +31,7 @@ func init() { signers = signersList } +// SetupAuthZSignerList sets the granter and grantee for all the signers func SetupAuthZSignerList(granter string, grantee sdk.AccAddress) { for k, v := range signers { v.GranterAddress = granter @@ -35,6 +40,7 @@ func SetupAuthZSignerList(granter string, grantee sdk.AccAddress) { } } +// GetSigner returns the signer for a given msgURL func GetSigner(msgURL string) Signer { return signers[msgURL] } diff --git a/zetaclient/authz/authz_signer_test.go b/zetaclient/authz/authz_signer_test.go index 00a25722c4..1cc70b3116 100644 --- a/zetaclient/authz/authz_signer_test.go +++ b/zetaclient/authz/authz_signer_test.go @@ -1 +1,3 @@ package authz_test + +// NOTE: test file currently created empty to add the package in the test coverage scope diff --git a/zetaclient/chains/bitcoin/observer/inbound.go b/zetaclient/chains/bitcoin/observer/inbound.go index e9b4c20d60..66c6057b22 100644 --- a/zetaclient/chains/bitcoin/observer/inbound.go +++ b/zetaclient/chains/bitcoin/observer/inbound.go @@ -25,7 +25,8 @@ import ( "github.com/zeta-chain/zetacore/zetaclient/zetacore" ) -// WatchInbound watches Bitcoin chain for incoming txs and post votes to zetacore +// WatchInbound watches Bitcoin chain for inbounds +// It starts a ticker and run ObserveInbound func (ob *Observer) WatchInbound() { ticker, err := types.NewDynamicTicker("Bitcoin_WatchInbound", ob.GetChainParams().InboundTicker) if err != nil { @@ -37,6 +38,7 @@ func (ob *Observer) WatchInbound() { ob.logger.Inbound.Info().Msgf("WatchInbound started for chain %d", ob.chain.ChainId) sampledLogger := ob.logger.Inbound.Sample(&zerolog.BasicSampler{N: 10}) + // ticker loop for { select { case <-ticker.C(): @@ -57,6 +59,7 @@ func (ob *Observer) WatchInbound() { } } +// ObserveInbound observes Bitcoin chain for inbounds and post votes to zetacore func (ob *Observer) ObserveInbound() error { // get and update latest block height cnt, err := ob.rpcClient.GetBlockCount() @@ -328,6 +331,7 @@ func FilterAndParseIncomingTx( return inbounds, nil } +// GetInboundVoteMessageFromBtcEvent converts a BTCInboundEvent to a MsgVoteInbound to enable voting on the inbound on zetacore func (ob *Observer) GetInboundVoteMessageFromBtcEvent(inbound *BTCInboundEvent) *crosschaintypes.MsgVoteInbound { ob.logger.Inbound.Debug().Msgf("Processing inbound: %s", inbound.TxHash) amount := big.NewFloat(inbound.Value) diff --git a/zetaclient/chains/bitcoin/observer/observer.go b/zetaclient/chains/bitcoin/observer/observer.go index 91f0d695f4..245fcf79bd 100644 --- a/zetaclient/chains/bitcoin/observer/observer.go +++ b/zetaclient/chains/bitcoin/observer/observer.go @@ -90,7 +90,7 @@ type BTCInboundEvent struct { TxHash string } -// BTCOutboundEvent contains bitcoin block and the header +// BTCBlockNHeader contains bitcoin block and the header type BTCBlockNHeader struct { Header *wire.BlockHeader Block *btcjson.GetBlockVerboseTxResult @@ -98,23 +98,44 @@ type BTCBlockNHeader struct { // Observer is the Bitcoin chain observer type Observer struct { + // BlockCache caches last block height and hash BlockCache *lru.Cache // Mu is lock for all the maps, utxos and core params Mu *sync.Mutex + // Tss is the TSS signer Tss interfaces.TSSSigner - chain chains.Chain - netParams *chaincfg.Params - rpcClient interfaces.BTCRPCClient - zetacoreClient interfaces.ZetacoreClient - lastBlock int64 + // chain contains static information about the chain being observed + chain chains.Chain + + // netParams contains the Bitcoin network parameters for the chain + netParams *chaincfg.Params + + // rpcClient is the Bitcoin RPC client to interact with the observed chain + rpcClient interfaces.BTCRPCClient + + // zetacoreClient is the Zetacore client to interact with ZetaChain + zetacoreClient interfaces.ZetacoreClient + + // lastBlock is the last block height of the observed chain + lastBlock int64 + + // lastBlockScanned is the last block height scanned by the observer lastBlockScanned int64 - pendingNonce uint64 - utxos []btcjson.ListUnspentResult - params observertypes.ChainParams - coreContext *context.ZetacoreContext + + // pendingNonce is the number of pending nonces for outbounds + pendingNonce uint64 + + // utxos contains the UTXOs owned by the TSS address + utxos []btcjson.ListUnspentResult + + // params contains the dynamic chain params for the observed chain + params observertypes.ChainParams + + // coreContext contains context for ZetaChain + coreContext *context.ZetacoreContext // includedTxHashes indexes included tx with tx hash includedTxHashes map[string]bool @@ -125,10 +146,17 @@ type Observer struct { // broadcastedTx indexes the outbound hash with the outbound tx identifier broadcastedTx map[string]string - db *gorm.DB - stop chan struct{} + // db is the database for the observer used to persist observation data + db *gorm.DB + + // stop is the channel to stop the observer + stop chan struct{} + + // logger contains the loggers used by the observer logger Logger - ts *metrics.TelemetryServer + + // ts is the telemetry server for metrics + ts *metrics.TelemetryServer } // NewObserver returns a new Bitcoin chain observer @@ -219,12 +247,14 @@ func NewObserver( return &ob, nil } +// WithZetacoreClient attaches the Zetacore client to the observer func (ob *Observer) WithZetacoreClient(client *zetacore.Client) { ob.Mu.Lock() defer ob.Mu.Unlock() ob.zetacoreClient = client } +// WithLogger attaches the logger to the observer func (ob *Observer) WithLogger(logger zerolog.Logger) { ob.Mu.Lock() defer ob.Mu.Unlock() @@ -237,37 +267,42 @@ func (ob *Observer) WithLogger(logger zerolog.Logger) { } } +// WithBtcClient attaches the Bitcoin RPC client to the observer func (ob *Observer) WithBtcClient(client *rpcclient.Client) { ob.Mu.Lock() defer ob.Mu.Unlock() ob.rpcClient = client } +// WithChain attaches the chain to the observer func (ob *Observer) WithChain(chain chains.Chain) { ob.Mu.Lock() defer ob.Mu.Unlock() ob.chain = chain } +// Chain returns the chain associated to the observed chain func (ob *Observer) Chain() chains.Chain { ob.Mu.Lock() defer ob.Mu.Unlock() return ob.chain } +// SetChainParams sets the chain params for the observer for the observed chain func (ob *Observer) SetChainParams(params observertypes.ChainParams) { ob.Mu.Lock() defer ob.Mu.Unlock() ob.params = params } +// GetChainParams returns the chain params for the observer for the observed chain func (ob *Observer) GetChainParams() observertypes.ChainParams { ob.Mu.Lock() defer ob.Mu.Unlock() return ob.params } -// Start starts the Go routine to observe the Bitcoin chain +// Start starts the Go routine processes to observe the Bitcoin chain func (ob *Observer) Start() { ob.logger.Chain.Info().Msgf("Bitcoin client is starting") go ob.WatchInbound() // watch bitcoin chain for incoming txs and post votes to zetacore @@ -340,36 +375,43 @@ func (ob *Observer) WatchRPCStatus() { } } +// Stop stops the Go routine processes observing the Bitcoin chain func (ob *Observer) Stop() { ob.logger.Chain.Info().Msgf("ob %s is stopping", ob.chain.String()) close(ob.stop) // this notifies all goroutines to stop ob.logger.Chain.Info().Msgf("%s observer stopped", ob.chain.String()) } +// SetLastBlockHeight sets the last block height of the chain func (ob *Observer) SetLastBlockHeight(height int64) { atomic.StoreInt64(&ob.lastBlock, height) } +// GetLastBlockHeight gets the last block height of the chain func (ob *Observer) GetLastBlockHeight() int64 { return atomic.LoadInt64(&ob.lastBlock) } +// SetLastBlockHeightScanned sets the last block height scanned by the observer func (ob *Observer) SetLastBlockHeightScanned(height int64) { atomic.StoreInt64(&ob.lastBlockScanned, height) metrics.LastScannedBlockNumber.WithLabelValues(ob.chain.ChainName.String()).Set(float64(height)) } +// GetLastBlockHeightScanned gets the last block height scanned by the observer func (ob *Observer) GetLastBlockHeightScanned() int64 { return atomic.LoadInt64(&ob.lastBlockScanned) } +// GetPendingNonce returns the number of pending nonces for outbounds func (ob *Observer) GetPendingNonce() uint64 { ob.Mu.Lock() defer ob.Mu.Unlock() return ob.pendingNonce } -// GetBaseGasPrice ... +// GetBaseGasPrice returns the base gas price for the chain +// Currently not used for Bitcoin // TODO: implement // https://github.com/zeta-chain/node/issues/868 func (ob *Observer) GetBaseGasPrice() *big.Int { @@ -425,6 +467,7 @@ func (ob *Observer) WatchGasPrice() { } } +// PostGasPrice posts the gas price to Zetacore func (ob *Observer) PostGasPrice() error { if ob.chain.ChainId == 18444 { //bitcoin regtest; hardcode here since this RPC is not available on regtest blockNumber, err := ob.rpcClient.GetBlockCount() @@ -512,6 +555,7 @@ func GetSenderAddressByVin(rpcClient interfaces.BTCRPCClient, vin btcjson.Vin, n } // WatchUTXOS watches bitcoin chain for UTXOs owned by the TSS address +// It starts a ticker to fetch UTXOs at regular intervals func (ob *Observer) WatchUTXOS() { ticker, err := clienttypes.NewDynamicTicker("Bitcoin_WatchUTXOS", ob.GetChainParams().WatchUtxoTicker) if err != nil { @@ -538,6 +582,7 @@ func (ob *Observer) WatchUTXOS() { } } +// FetchUTXOS fetches UTXOs owned by the TSS address func (ob *Observer) FetchUTXOS() error { defer func() { if err := recover(); err != nil { @@ -689,6 +734,7 @@ func GetRawTxResult( return btcjson.TxRawResult{}, fmt.Errorf("getRawTxResult: tx %s not included yet", hash) } +// BuildBroadcastedTxMap creates a map of broadcasted transactions from the database func (ob *Observer) BuildBroadcastedTxMap() error { var broadcastedTransactions []clienttypes.OutboundHashSQLType if err := ob.db.Find(&broadcastedTransactions).Error; err != nil { @@ -734,6 +780,7 @@ func (ob *Observer) LoadLastScannedBlock() error { return nil } +// GetBlockByNumberCached returns the block by number from the cache func (ob *Observer) GetBlockByNumberCached(blockNumber int64) (*BTCBlockNHeader, error) { if result, ok := ob.BlockCache.Get(blockNumber); ok { return result.(*BTCBlockNHeader), nil @@ -805,6 +852,7 @@ func (ob *Observer) postBlockHeader(tip int64) error { return err } +// loadDB loads the observer database func (ob *Observer) loadDB(dbpath string) error { if _, err := os.Stat(dbpath); os.IsNotExist(err) { err := os.MkdirAll(dbpath, os.ModePerm) diff --git a/zetaclient/chains/bitcoin/observer/outbound.go b/zetaclient/chains/bitcoin/observer/outbound.go index a17d46883f..3d79e3bae4 100644 --- a/zetaclient/chains/bitcoin/observer/outbound.go +++ b/zetaclient/chains/bitcoin/observer/outbound.go @@ -327,6 +327,8 @@ func (ob *Observer) refreshPendingNonce() { } } +// getOutboundIDByNonce gets the outbound ID from the nonce of the outbound transaction. +// test is true for unit test only. func (ob *Observer) getOutboundIDByNonce(nonce uint64, test bool) (string, error) { // There are 2 types of txids an observer can trust @@ -362,6 +364,7 @@ func (ob *Observer) getOutboundIDByNonce(nonce uint64, test bool) (string, error return "", fmt.Errorf("getOutboundIDByNonce: cannot find outbound txid for nonce %d", nonce) } +// findNonceMarkUTXO finds the nonce-mark UTXO in the list of UTXOs. func (ob *Observer) findNonceMarkUTXO(nonce uint64, txid string) (int, error) { tssAddress := ob.Tss.BTCAddressWitnessPubkeyHash().EncodeAddress() amount := chains.NonceMarkAmount(nonce) diff --git a/zetaclient/chains/bitcoin/signer/signer.go b/zetaclient/chains/bitcoin/signer/signer.go index 0c51fc7204..2d0a9f63d2 100644 --- a/zetaclient/chains/bitcoin/signer/signer.go +++ b/zetaclient/chains/bitcoin/signer/signer.go @@ -45,14 +45,26 @@ var _ interfaces.ChainSigner = &Signer{} // Signer deals with signing BTC transactions and implements the ChainSigner interface type Signer struct { - tssSigner interfaces.TSSSigner - rpcClient interfaces.BTCRPCClient - logger zerolog.Logger + // tssSigner is the TSS signer object used to sign transactions + tssSigner interfaces.TSSSigner + + // rpcClient is the RPC client used to broadcast transactions on the external network + rpcClient interfaces.BTCRPCClient + + // logger is the logger used by the signer + logger zerolog.Logger + + // loggerCompliance is the logger used for compliance logging loggerCompliance zerolog.Logger - ts *metrics.TelemetryServer - coreContext *context.ZetacoreContext + + // ts is the telemetry server used to record metrics + ts *metrics.TelemetryServer + + // coreContext contains context data of ZetaChain + coreContext *context.ZetacoreContext } +// NewSigner creates a new BTC signer func NewSigner( cfg config.BTCConfig, tssSigner interfaces.TSSSigner, @@ -287,6 +299,7 @@ func (signer *Signer) SignWithdrawTx( return tx, nil } +// Broadcast sends the signed transaction to the network func (signer *Signer) Broadcast(signedTx *wire.MsgTx) error { fmt.Printf("BTCSigner: Broadcasting: %s\n", signedTx.TxHash().String()) @@ -307,6 +320,7 @@ func (signer *Signer) Broadcast(signedTx *wire.MsgTx) error { return nil } +// TryProcessOutbound signs and broadcasts a BTC transaction from a new outbound func (signer *Signer) TryProcessOutbound( cctx *types.CrossChainTx, outboundProcessor *outboundprocessor.Processor, diff --git a/zetaclient/chains/bitcoin/utils.go b/zetaclient/chains/bitcoin/utils.go index fe2bb2481b..0bc3fdcb48 100644 --- a/zetaclient/chains/bitcoin/utils.go +++ b/zetaclient/chains/bitcoin/utils.go @@ -8,6 +8,7 @@ import ( "github.com/pkg/errors" ) +// PrettyPrintStruct returns a pretty-printed string representation of a struct func PrettyPrintStruct(val interface{}) (string, error) { prettyStruct, err := json.MarshalIndent( val, @@ -20,6 +21,7 @@ func PrettyPrintStruct(val interface{}) (string, error) { return string(prettyStruct), nil } +// GetSatoshis converts a bitcoin amount to satoshis func GetSatoshis(btc float64) (int64, error) { // The amount is only considered invalid if it cannot be represented // as an integer type. This may happen if f is NaN or +-Infinity. @@ -39,6 +41,7 @@ func GetSatoshis(btc float64) (int64, error) { return round(btc * btcutil.SatoshiPerBitcoin), nil } +// round rounds a float64 to the nearest integer func round(f float64) int64 { if f < 0 { // #nosec G701 always in range From b1ea5d9d4008630ed78516e9d0f92c5054893d2a Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 5 Jun 2024 14:03:30 +0200 Subject: [PATCH 02/16] add revamp todos --- zetaclient/chains/bitcoin/observer/inbound.go | 6 ++++++ .../chains/bitcoin/observer/observer.go | 19 ++++++++++++++++++- .../chains/bitcoin/observer/outbound.go | 5 +++++ zetaclient/chains/bitcoin/signer/signer.go | 2 ++ zetaclient/chains/bitcoin/utils.go | 2 ++ 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/zetaclient/chains/bitcoin/observer/inbound.go b/zetaclient/chains/bitcoin/observer/inbound.go index 66c6057b22..1d82746e81 100644 --- a/zetaclient/chains/bitcoin/observer/inbound.go +++ b/zetaclient/chains/bitcoin/observer/inbound.go @@ -27,6 +27,7 @@ import ( // WatchInbound watches Bitcoin chain for inbounds // It starts a ticker and run ObserveInbound +// TODO(revamp): move all ticker related methods in the same file func (ob *Observer) WatchInbound() { ticker, err := types.NewDynamicTicker("Bitcoin_WatchInbound", ob.GetChainParams().InboundTicker) if err != nil { @@ -60,6 +61,7 @@ func (ob *Observer) WatchInbound() { } // ObserveInbound observes Bitcoin chain for inbounds and post votes to zetacore +// TODO(revamp): simplify this function into smaller functions func (ob *Observer) ObserveInbound() error { // get and update latest block height cnt, err := ob.rpcClient.GetBlockCount() @@ -174,6 +176,7 @@ func (ob *Observer) ObserveInbound() error { } // WatchInboundTracker watches zetacore for bitcoin inbound trackers +// TODO(revamp): move all ticker related methods in the same file func (ob *Observer) WatchInboundTracker() { ticker, err := types.NewDynamicTicker("Bitcoin_WatchInboundTracker", ob.GetChainParams().InboundTicker) if err != nil { @@ -203,6 +206,7 @@ func (ob *Observer) WatchInboundTracker() { } // ProcessInboundTrackers processes inbound trackers +// TODO(revamp): move inbound tracker logic in a specific file func (ob *Observer) ProcessInboundTrackers() error { trackers, err := ob.zetacoreClient.GetInboundTrackersForChain(ob.chain.ChainId) if err != nil { @@ -364,6 +368,7 @@ func (ob *Observer) GetInboundVoteMessageFromBtcEvent(inbound *BTCInboundEvent) } // DoesInboundContainsRestrictedAddress returns true if the inbound contains restricted addresses +// TODO(revamp): move all compliance related functions in a specific file func (ob *Observer) DoesInboundContainsRestrictedAddress(inTx *BTCInboundEvent) bool { receiver := "" parsedAddress, _, err := chains.ParseAddressAndData(hex.EncodeToString(inTx.MemoBytes)) @@ -380,6 +385,7 @@ func (ob *Observer) DoesInboundContainsRestrictedAddress(inTx *BTCInboundEvent) // GetBtcEvent either returns a valid BTCInboundEvent or nil // Note: the caller should retry the tx on error (e.g., GetSenderAddressByVin failed) +// TODO(revamp): simplify this function func GetBtcEvent( rpcClient interfaces.BTCRPCClient, tx btcjson.TxRawResult, diff --git a/zetaclient/chains/bitcoin/observer/observer.go b/zetaclient/chains/bitcoin/observer/observer.go index 245fcf79bd..05f63bba87 100644 --- a/zetaclient/chains/bitcoin/observer/observer.go +++ b/zetaclient/chains/bitcoin/observer/observer.go @@ -52,7 +52,7 @@ const ( var _ interfaces.ChainObserver = &Observer{} // Logger contains list of loggers used by Bitcoin chain observer -// TODO: Merge this logger with the one in evm +// TODO(revamp): Merge this logger with the one in evm // https://github.com/zeta-chain/node/issues/2022 type Logger struct { // Chain is the parent logger for the chain @@ -75,6 +75,7 @@ type Logger struct { } // BTCInboundEvent represents an incoming transaction event +// TODO(revamp): Move to inbound type BTCInboundEvent struct { // FromAddress is the first input address FromAddress string @@ -314,6 +315,8 @@ func (ob *Observer) Start() { } // WatchRPCStatus watches the RPC status of the Bitcoin chain +// TODO(revamp): move ticker related functions to a specific file +// TODO(revamp): move inner logic in a separate function func (ob *Observer) WatchRPCStatus() { ob.logger.Chain.Info().Msgf("RPCStatus is starting") ticker := time.NewTicker(60 * time.Second) @@ -432,6 +435,8 @@ func (ob *Observer) ConfirmationsThreshold(amount *big.Int) int64 { } // WatchGasPrice watches Bitcoin chain for gas rate and post to zetacore +// TODO(revamp): move ticker related functions to a specific file +// TODO(revamp): move inner logic in a separate function func (ob *Observer) WatchGasPrice() { // report gas price right away as the ticker takes time to kick in err := ob.PostGasPrice() @@ -468,6 +473,7 @@ func (ob *Observer) WatchGasPrice() { } // PostGasPrice posts the gas price to Zetacore +// TODO(revamp): move to gas price file func (ob *Observer) PostGasPrice() error { if ob.chain.ChainId == 18444 { //bitcoin regtest; hardcode here since this RPC is not available on regtest blockNumber, err := ob.rpcClient.GetBlockCount() @@ -513,6 +519,7 @@ func (ob *Observer) PostGasPrice() error { } // GetSenderAddressByVin get the sender address from the previous transaction +// TODO(revamp): move in upper package func GetSenderAddressByVin(rpcClient interfaces.BTCRPCClient, vin btcjson.Vin, net *chaincfg.Params) (string, error) { // query previous raw transaction by txid // GetTransaction requires reconfiguring the bitcoin node (txindex=1), so we use GetRawTransaction instead @@ -556,6 +563,7 @@ func GetSenderAddressByVin(rpcClient interfaces.BTCRPCClient, vin btcjson.Vin, n // WatchUTXOS watches bitcoin chain for UTXOs owned by the TSS address // It starts a ticker to fetch UTXOs at regular intervals +// TODO(revamp): move ticker related functions to a specific file func (ob *Observer) WatchUTXOS() { ticker, err := clienttypes.NewDynamicTicker("Bitcoin_WatchUTXOS", ob.GetChainParams().WatchUtxoTicker) if err != nil { @@ -583,6 +591,7 @@ func (ob *Observer) WatchUTXOS() { } // FetchUTXOS fetches UTXOs owned by the TSS address +// TODO(revamp): move to UTXO file func (ob *Observer) FetchUTXOS() error { defer func() { if err := recover(); err != nil { @@ -646,6 +655,7 @@ func (ob *Observer) FetchUTXOS() error { } // SaveBroadcastedTx saves successfully broadcasted transaction +// TODO(revamp): move to db file func (ob *Observer) SaveBroadcastedTx(txHash string, nonce uint64) { outboundID := ob.GetTxID(nonce) ob.Mu.Lock() @@ -662,6 +672,7 @@ func (ob *Observer) SaveBroadcastedTx(txHash string, nonce uint64) { } // GetTxResultByHash gets the transaction result by hash +// TODO(revamp): move to client package func GetTxResultByHash( rpcClient interfaces.BTCRPCClient, txID string, @@ -680,6 +691,7 @@ func GetTxResultByHash( } // GetBlockHeightByHash gets the block height by block hash +// TODO(revamp): move to client package func GetBlockHeightByHash( rpcClient interfaces.BTCRPCClient, hash string, @@ -700,6 +712,7 @@ func GetBlockHeightByHash( } // GetRawTxResult gets the raw tx result +// TODO(revamp): move to client package func GetRawTxResult( rpcClient interfaces.BTCRPCClient, hash *chainhash.Hash, @@ -735,6 +748,7 @@ func GetRawTxResult( } // BuildBroadcastedTxMap creates a map of broadcasted transactions from the database +// TODO(revamp): move to db file func (ob *Observer) BuildBroadcastedTxMap() error { var broadcastedTransactions []clienttypes.OutboundHashSQLType if err := ob.db.Find(&broadcastedTransactions).Error; err != nil { @@ -749,6 +763,7 @@ func (ob *Observer) BuildBroadcastedTxMap() error { // LoadLastScannedBlock loads last scanned block from database // The last scanned block is the height from which the observer should continue scanning for inbound transactions +// TODO(revamp): move to db file func (ob *Observer) LoadLastScannedBlock() error { // Get the latest block number from node bn, err := ob.rpcClient.GetBlockCount() @@ -817,6 +832,7 @@ func (ob *Observer) isTssTransaction(txid string) bool { } // postBlockHeader posts block header to zetacore +// TODO(revamp): move to block header file func (ob *Observer) postBlockHeader(tip int64) error { ob.logger.Inbound.Info().Msgf("postBlockHeader: tip %d", tip) bn := tip @@ -853,6 +869,7 @@ func (ob *Observer) postBlockHeader(tip int64) error { } // loadDB loads the observer database +// TODO(revamp): move to db file func (ob *Observer) loadDB(dbpath string) error { if _, err := os.Stat(dbpath); os.IsNotExist(err) { err := os.MkdirAll(dbpath, os.ModePerm) diff --git a/zetaclient/chains/bitcoin/observer/outbound.go b/zetaclient/chains/bitcoin/observer/outbound.go index 3d79e3bae4..24739b0692 100644 --- a/zetaclient/chains/bitcoin/observer/outbound.go +++ b/zetaclient/chains/bitcoin/observer/outbound.go @@ -26,6 +26,8 @@ func (ob *Observer) GetTxID(nonce uint64) string { } // WatchOutbound watches Bitcoin chain for outgoing txs status +// TODO(revamp): move ticker functions to a specific file +// TODO(revamp): move into a separate package func (ob *Observer) WatchOutbound() { ticker, err := types.NewDynamicTicker("Bitcoin_WatchOutbound", ob.GetChainParams().OutboundTicker) if err != nil { @@ -109,6 +111,7 @@ func (ob *Observer) WatchOutbound() { } // IsOutboundProcessed returns isIncluded(or inMempool), isConfirmed, Error +// TODO(revamp): rename as it vote the outbound and doesn't only check if outbound is processed func (ob *Observer) IsOutboundProcessed(cctx *crosschaintypes.CrossChainTx, logger zerolog.Logger) (bool, bool, error) { params := *cctx.GetCurrentOutboundParam() sendHash := cctx.Index @@ -211,6 +214,8 @@ func (ob *Observer) IsOutboundProcessed(cctx *crosschaintypes.CrossChainTx, logg // - the total value of the selected UTXOs. // - the number of consolidated UTXOs. // - the total value of the consolidated UTXOs. +// +// TODO(revamp): move to utxo file func (ob *Observer) SelectUTXOs( amount float64, utxosToSpend uint16, diff --git a/zetaclient/chains/bitcoin/signer/signer.go b/zetaclient/chains/bitcoin/signer/signer.go index 2d0a9f63d2..159c4f6577 100644 --- a/zetaclient/chains/bitcoin/signer/signer.go +++ b/zetaclient/chains/bitcoin/signer/signer.go @@ -177,6 +177,7 @@ func (signer *Signer) AddWithdrawTxOutputs( } // SignWithdrawTx receives utxos sorted by value, amount in BTC, feeRate in BTC per Kb +// TODO(revamp): simplify the function func (signer *Signer) SignWithdrawTx( to btcutil.Address, amount float64, @@ -321,6 +322,7 @@ func (signer *Signer) Broadcast(signedTx *wire.MsgTx) error { } // TryProcessOutbound signs and broadcasts a BTC transaction from a new outbound +// TODO(revamp): simplify the function func (signer *Signer) TryProcessOutbound( cctx *types.CrossChainTx, outboundProcessor *outboundprocessor.Processor, diff --git a/zetaclient/chains/bitcoin/utils.go b/zetaclient/chains/bitcoin/utils.go index 0bc3fdcb48..8c37e01fad 100644 --- a/zetaclient/chains/bitcoin/utils.go +++ b/zetaclient/chains/bitcoin/utils.go @@ -8,6 +8,8 @@ import ( "github.com/pkg/errors" ) +// TODO(revamp): Remove utils.go and move the functions to the appropriate files + // PrettyPrintStruct returns a pretty-printed string representation of a struct func PrettyPrintStruct(val interface{}) (string, error) { prettyStruct, err := json.MarshalIndent( From 04c1e33db9324fdd034174e392618f05896baf1f Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 5 Jun 2024 14:33:44 +0200 Subject: [PATCH 03/16] evm --- zetaclient/chains/evm/observer/inbound.go | 4 + zetaclient/chains/evm/observer/observer.go | 87 ++++++++++++++++++---- zetaclient/chains/evm/observer/outbound.go | 3 + zetaclient/chains/evm/signer/signer.go | 14 ++++ 4 files changed, 92 insertions(+), 16 deletions(-) diff --git a/zetaclient/chains/evm/observer/inbound.go b/zetaclient/chains/evm/observer/inbound.go index 373536fe6d..b04dc593b3 100644 --- a/zetaclient/chains/evm/observer/inbound.go +++ b/zetaclient/chains/evm/observer/inbound.go @@ -34,6 +34,7 @@ import ( ) // WatchInbound watches evm chain for incoming txs and post votes to zetacore +// TODO(revamp): move ticker function to a separate file func (ob *Observer) WatchInbound() { ticker, err := clienttypes.NewDynamicTicker( fmt.Sprintf("EVM_WatchInbound_%d", ob.chain.ChainId), @@ -70,6 +71,7 @@ func (ob *Observer) WatchInbound() { // WatchInboundTracker gets a list of Inbound tracker suggestions from zeta-core at each tick and tries to check if the in-tx was confirmed. // If it was, it tries to broadcast the confirmation vote. If this zeta client has previously broadcast the vote, the tx would be rejected +// TODO(revamp): move inbound tracker function to a separate file func (ob *Observer) WatchInboundTracker() { ticker, err := clienttypes.NewDynamicTicker( fmt.Sprintf("EVM_WatchInboundTracker_%d", ob.chain.ChainId), @@ -101,6 +103,7 @@ func (ob *Observer) WatchInboundTracker() { } // ProcessInboundTrackers processes inbound trackers from zetacore +// TODO(revamp): move inbound tracker function to a separate file func (ob *Observer) ProcessInboundTrackers() error { trackers, err := ob.zetacoreClient.GetInboundTrackersForChain(ob.chain.ChainId) if err != nil { @@ -147,6 +150,7 @@ func (ob *Observer) ProcessInboundTrackers() error { return nil } +// ObserveInbound observes the evm chain for inbounds and posts votes to zetacore func (ob *Observer) ObserveInbound(sampledLogger zerolog.Logger) error { // get and update latest block height blockNumber, err := ob.evmClient.BlockNumber(context.Background()) diff --git a/zetaclient/chains/evm/observer/observer.go b/zetaclient/chains/evm/observer/observer.go index 4a38a62d12..c61b0f78b8 100644 --- a/zetaclient/chains/evm/observer/observer.go +++ b/zetaclient/chains/evm/observer/observer.go @@ -40,7 +40,7 @@ import ( ) // Logger is the logger for evm chains -// TODO: Merge this logger with the one in bitcoin +// TODO(revamp): Merge this logger with the one in bitcoin // https://github.com/zeta-chain/node/issues/2022 type Logger struct { // Chain is the parent logger for the chain @@ -63,27 +63,61 @@ var _ interfaces.ChainObserver = &Observer{} // Observer is the observer for evm chains type Observer struct { + // Tss is the TSS signer for the chain Tss interfaces.TSSSigner + // Mu is the mutex for the observer Mu *sync.Mutex - chain chains.Chain - evmClient interfaces.EVMRPCClient - evmJSONRPC interfaces.EVMJSONRPCClient - zetacoreClient interfaces.ZetacoreClient - lastBlockScanned uint64 - lastBlock uint64 - db *gorm.DB - outboundPendingTransactions map[string]*ethtypes.Transaction - outboundConfirmedReceipts map[string]*ethtypes.Receipt + // chain contains static chain information of the observed chain + chain chains.Chain + + // evmClient is the EVM client for the observed chain + evmClient interfaces.EVMRPCClient + + // evmJSONRPC is the EVM JSON RPC client for the observed chain + evmJSONRPC interfaces.EVMJSONRPCClient + + // zetacoreClient is the client to interact with ZetaChain + zetacoreClient interfaces.ZetacoreClient + + // lastBlockScanned is the last block height scanned by the observer + lastBlockScanned uint64 + + // lastBlock is the last block height of the chain + lastBlock uint64 + + // db is the database to persist observation data + db *gorm.DB + + // outboundPendingTransactions is the map to index pending transactions by hash + outboundPendingTransactions map[string]*ethtypes.Transaction + + // outboundConfirmedReceipts is the map to index confirmed receipts by hash + outboundConfirmedReceipts map[string]*ethtypes.Receipt + + // outboundConfirmedTransactions is the map to index confirmed transactions by hash outboundConfirmedTransactions map[string]*ethtypes.Transaction - stop chan struct{} - logger Logger - coreContext *clientcontext.ZetacoreContext - chainParams observertypes.ChainParams - ts *metrics.TelemetryServer - blockCache *lru.Cache + // stop is the channel to signal the observer to stop + stop chan struct{} + + // logger is the logger for the observer + logger Logger + + // coreContext contains context data of ZetaChain + coreContext *clientcontext.ZetacoreContext + + // chainParams contains the dynamic chain parameters of the observed chain + chainParams observertypes.ChainParams + + // ts is the telemetry server for metrics + ts *metrics.TelemetryServer + + // blockCache is the cache for blocks + blockCache *lru.Cache + + // headerCache is the cache for headers headerCache *lru.Cache } @@ -251,6 +285,8 @@ func (ob *Observer) GetERC20CustodyContract() (ethcommon.Address, *erc20custody. return addr, contract, err } +// FetchConnectorContract fetches the connector contract +// TODO(revamp): move this to a contract package func FetchConnectorContract( addr ethcommon.Address, client interfaces.EVMRPCClient, @@ -258,6 +294,8 @@ func FetchConnectorContract( return zetaconnector.NewZetaConnectorNonEth(addr, client) } +// FetchConnectorContractEth fetches the connector contract for eth +// TODO(revamp): move this to a contract package func FetchConnectorContractEth( addr ethcommon.Address, client interfaces.EVMRPCClient, @@ -265,6 +303,8 @@ func FetchConnectorContractEth( return zetaconnectoreth.NewZetaConnectorEth(addr, client) } +// FetchZetaZetaNonEthTokenContract fetches the zeta token contract +// TODO(revamp): move this to a contract package func FetchZetaZetaNonEthTokenContract( addr ethcommon.Address, client interfaces.EVMRPCClient, @@ -272,6 +312,8 @@ func FetchZetaZetaNonEthTokenContract( return zeta.NewZetaNonEth(addr, client) } +// FetchERC20CustodyContract fetches the erc20 custody contract +// TODO(revamp): move this to a contract package func FetchERC20CustodyContract( addr ethcommon.Address, client interfaces.EVMRPCClient, @@ -298,6 +340,8 @@ func (ob *Observer) Start() { } // WatchRPCStatus watches the RPC status of the evm chain +// TODO(revamp): move ticker to ticker file +// TODO(revamp): move inner logic to a separate function func (ob *Observer) WatchRPCStatus() { ob.logger.Chain.Info().Msgf("Starting RPC status check for chain %s", ob.chain.String()) ticker := time.NewTicker(60 * time.Second) @@ -338,6 +382,7 @@ func (ob *Observer) WatchRPCStatus() { } } +// Stop all observation routines for the evm chain func (ob *Observer) Stop() { ob.logger.Chain.Info().Msgf("ob %s is stopping", ob.chain.String()) close(ob.stop) // this notifies all goroutines to stop @@ -442,6 +487,8 @@ func (ob *Observer) GetLastBlockHeight() uint64 { } // WatchGasPrice watches evm chain for gas prices and post to zetacore +// TODO(revamp): move ticker to ticker file +// TODO(revamp): move inner logic to a separate function func (ob *Observer) WatchGasPrice() { // report gas price right away as the ticker takes time to kick in err := ob.PostGasPrice() @@ -480,6 +527,8 @@ func (ob *Observer) WatchGasPrice() { } } +// PostGasPrice posts gas price to zetacore +// TODO(revamp): move to gas price file func (ob *Observer) PostGasPrice() error { // GAS PRICE @@ -508,6 +557,7 @@ func (ob *Observer) PostGasPrice() error { } // TransactionByHash query transaction by hash via JSON-RPC +// TODO(revamp): move to a tx file func (ob *Observer) TransactionByHash(txHash string) (*ethrpc.Transaction, bool, error) { tx, err := ob.evmJSONRPC.EthGetTransactionByHash(txHash) if err != nil { @@ -520,6 +570,7 @@ func (ob *Observer) TransactionByHash(txHash string) (*ethrpc.Transaction, bool, return tx, tx.BlockNumber == nil, nil } +// GetBlockHeaderCached get block header by number from cache func (ob *Observer) GetBlockHeaderCached(blockNumber uint64) (*ethtypes.Header, error) { if header, ok := ob.headerCache.Get(blockNumber); ok { return header.(*ethtypes.Header), nil @@ -572,6 +623,7 @@ func (ob *Observer) BlockByNumber(blockNumber int) (*ethrpc.Block, error) { // LoadLastScannedBlock loads last scanned block from specified height or from database // The last scanned block is the height from which the observer should continue scanning for inbound transactions +// TODO(revamp): move to a db file func (ob *Observer) LoadLastScannedBlock() error { // get environment variable envvar := ob.chain.ChainName.String() + "_SCAN_FROM" @@ -618,6 +670,7 @@ func (ob *Observer) LoadLastScannedBlock() error { } // LoadDB open sql database and load data into EVM observer +// TODO(revamp): move to a db file func (ob *Observer) LoadDB(dbPath string, chain chains.Chain) error { if dbPath != "" { if _, err := os.Stat(dbPath); os.IsNotExist(err) { @@ -652,6 +705,8 @@ func (ob *Observer) LoadDB(dbPath string, chain chains.Chain) error { return nil } +// postBlockHeader posts the block header to zetacore +// TODO(revamp): move to a block header file func (ob *Observer) postBlockHeader(tip uint64) error { bn := tip diff --git a/zetaclient/chains/evm/observer/outbound.go b/zetaclient/chains/evm/observer/outbound.go index 8dda7ac034..01267e9ff0 100644 --- a/zetaclient/chains/evm/observer/outbound.go +++ b/zetaclient/chains/evm/observer/outbound.go @@ -34,6 +34,8 @@ func (ob *Observer) GetTxID(nonce uint64) string { } // WatchOutbound watches evm chain for outgoing txs status +// TODO(revamp): move ticker function to ticker file +// TODO(revamp): move inner logic to a separate function func (ob *Observer) WatchOutbound() { ticker, err := clienttypes.NewDynamicTicker( fmt.Sprintf("EVM_WatchOutbound_%d", ob.chain.ChainId), @@ -130,6 +132,7 @@ func (ob *Observer) PostVoteOutbound( // IsOutboundProcessed checks outbound status and returns (isIncluded, isConfirmed, error) // It also posts vote to zetacore if the tx is confirmed +// TODO(revamp): rename as it also vote the outbound func (ob *Observer) IsOutboundProcessed(cctx *crosschaintypes.CrossChainTx, logger zerolog.Logger) (bool, bool, error) { // skip if outbound is not confirmed nonce := cctx.GetCurrentOutboundParam().TssNonce diff --git a/zetaclient/chains/evm/signer/signer.go b/zetaclient/chains/evm/signer/signer.go index 00f6f35fd5..32b3152cd0 100644 --- a/zetaclient/chains/evm/signer/signer.go +++ b/zetaclient/chains/evm/signer/signer.go @@ -65,6 +65,7 @@ type Signer struct { outboundHashBeingReported map[string]bool } +// NewSigner creates a new EVM signer func NewSigner( chain chains.Chain, endpoint string, @@ -318,6 +319,7 @@ func (signer *Signer) SignCommandTx(txData *OutboundData, cmd string, params str // TryProcessOutbound - signer interface implementation // This function will attempt to build and sign an evm transaction using the TSS signer. // It will then broadcast the signed transaction to the outbound chain. +// TODO(revamp): simplify function func (signer *Signer) TryProcessOutbound( cctx *types.CrossChainTx, outboundProc *outboundprocessor.Processor, @@ -607,14 +609,19 @@ func (signer *Signer) GetReportedTxList() *map[string]bool { return &signer.outboundHashBeingReported } +// EvmClient returns the EVM RPC client func (signer *Signer) EvmClient() interfaces.EVMRPCClient { return signer.client } +// EvmSigner returns the EVM signer object for the signer func (signer *Signer) EvmSigner() ethtypes.Signer { + // TODO(revamp): rename field into evmSigner return signer.ethSigner } +// IsSenderZetaChain checks if the sender chain is ZetaChain +// TODO(revamp): move to another package more general for cctx functions func IsSenderZetaChain( cctx *types.CrossChainTx, zetacoreClient interfaces.ZetacoreClient, @@ -624,6 +631,7 @@ func IsSenderZetaChain( cctx.CctxStatus.Status == types.CctxStatus_PendingOutbound && flags.IsOutboundEnabled } +// ErrorMsg returns a error message for SignOutbound failure with cctx data func ErrorMsg(cctx *types.CrossChainTx) string { return fmt.Sprintf( "signer SignOutbound error: nonce %d chain %d", @@ -632,6 +640,8 @@ func ErrorMsg(cctx *types.CrossChainTx) string { ) } +// SignWhitelistERC20Cmd signs a whitelist command for ERC20 token +// TODO(revamp): move the cmd in a specific file func (signer *Signer) SignWhitelistERC20Cmd(txData *OutboundData, params string) (*ethtypes.Transaction, error) { outboundParams := txData.outboundParams erc20 := ethcommon.HexToAddress(params) @@ -661,6 +671,8 @@ func (signer *Signer) SignWhitelistERC20Cmd(txData *OutboundData, params string) return tx, nil } +// SignMigrateTssFundsCmd signs a migrate TSS funds command +// TODO(revamp): move the cmd in a specific file func (signer *Signer) SignMigrateTssFundsCmd(txData *OutboundData) (*ethtypes.Transaction, error) { tx, _, _, err := signer.Sign( nil, @@ -678,6 +690,7 @@ func (signer *Signer) SignMigrateTssFundsCmd(txData *OutboundData) (*ethtypes.Tr } // reportToOutboundTracker reports outboundHash to tracker only when tx receipt is available +// TODO(revamp): move outbound tracker function to a outbound tracker file func (signer *Signer) reportToOutboundTracker( zetacoreClient interfaces.ZetacoreClient, chainID int64, @@ -810,6 +823,7 @@ func getEVMRPC(endpoint string) (interfaces.EVMRPCClient, ethtypes.Signer, error return client, ethSigner, nil } +// roundUpToNearestGwei rounds up the gas price to the nearest Gwei func roundUpToNearestGwei(gasPrice *big.Int) *big.Int { oneGwei := big.NewInt(1_000_000_000) // 1 Gwei mod := new(big.Int) From 1fc8358fa02648fb794cbce68a75fd007c6c6554 Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 5 Jun 2024 14:43:47 +0200 Subject: [PATCH 04/16] config --- zetaclient/config/config.go | 6 ++++++ zetaclient/config/config_chain.go | 12 ++++++++++++ zetaclient/config/types.go | 19 +++++++++++++++++-- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/zetaclient/config/config.go b/zetaclient/config/config.go index 8680071c3c..916f9041c1 100644 --- a/zetaclient/config/config.go +++ b/zetaclient/config/config.go @@ -11,7 +11,10 @@ import ( // restrictedAddressBook is a map of restricted addresses var restrictedAddressBook = map[string]bool{} +// filename is config file name for ZetaClient const filename string = "zetaclient_config.json" + +// folder is the folder name for ZetaClient config const folder string = "config" // Save saves ZetaClient config @@ -78,10 +81,12 @@ func Load(path string) (Config, error) { return cfg, nil } +// LoadComplianceConfig loads compliance data (restricted addresses) from config func LoadComplianceConfig(cfg Config) { restrictedAddressBook = cfg.GetRestrictedAddressBook() } +// GetPath returns the absolute path of the input path func GetPath(inputPath string) string { path := strings.Split(inputPath, "/") if len(path) > 0 { @@ -93,6 +98,7 @@ func GetPath(inputPath string) string { path[0] = home } } + return filepath.Join(path...) } diff --git a/zetaclient/config/config_chain.go b/zetaclient/config/config_chain.go index 12c889f6af..5c2ed1d077 100644 --- a/zetaclient/config/config_chain.go +++ b/zetaclient/config/config_chain.go @@ -7,20 +7,29 @@ const ( ) const ( + // ConnectorAbiString is the ABI of the connector contract + // TODO(revamp): we should be able to use info from Go binding ConnectorAbiString = ` [{"inputs":[{"internalType":"address","name":"_zetaTokenAddress","type":"address"},{"internalType":"address","name":"_tssAddress","type":"address"},{"internalType":"address","name":"_tssAddressUpdater","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"originSenderAddress","type":"bytes"},{"indexed":true,"internalType":"uint256","name":"originChainId","type":"uint256"},{"indexed":true,"internalType":"address","name":"destinationAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"zetaAmount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"},{"indexed":true,"internalType":"bytes32","name":"internalSendHash","type":"bytes32"}],"name":"ZetaReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"originSenderAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"originChainId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"indexed":true,"internalType":"bytes","name":"destinationAddress","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"zetaAmount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"},{"indexed":true,"internalType":"bytes32","name":"internalSendHash","type":"bytes32"}],"name":"ZetaReverted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"originSenderAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"destinationAddress","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"zetaAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"gasLimit","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"zetaParams","type":"bytes"}],"name":"ZetaSent","type":"event"},{"inputs":[],"name":"getLockedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"originSenderAddress","type":"bytes"},{"internalType":"uint256","name":"originChainId","type":"uint256"},{"internalType":"address","name":"destinationAddress","type":"address"},{"internalType":"uint256","name":"zetaAmount","type":"uint256"},{"internalType":"bytes","name":"message","type":"bytes"},{"internalType":"bytes32","name":"internalSendHash","type":"bytes32"}],"name":"onReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"originSenderAddress","type":"address"},{"internalType":"uint256","name":"originChainId","type":"uint256"},{"internalType":"bytes","name":"destinationAddress","type":"bytes"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"uint256","name":"zetaAmount","type":"uint256"},{"internalType":"bytes","name":"message","type":"bytes"},{"internalType":"bytes32","name":"internalSendHash","type":"bytes32"}],"name":"onRevert","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceTssAddressUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"bytes","name":"destinationAddress","type":"bytes"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"bytes","name":"message","type":"bytes"},{"internalType":"uint256","name":"zetaAmount","type":"uint256"},{"internalType":"bytes","name":"zetaParams","type":"bytes"}],"internalType":"struct ZetaInterfaces.SendInput","name":"input","type":"tuple"}],"name":"send","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tssAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tssAddressUpdater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tssAddress","type":"address"}],"name":"updateTssAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"zetaToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]` + + // ERC20CustodyAbiString is the ABI of the erc20 custodu contract + // TODO(revamp): we should be able to use info from Go binding ERC20CustodyAbiString = ` [{"inputs":[{"internalType":"address","name":"_TSSAddress","type":"address"},{"internalType":"address","name":"_TSSAddressUpdater","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidSender","type":"error"},{"inputs":[],"name":"InvalidTSSUpdater","type":"error"},{"inputs":[],"name":"IsPaused","type":"error"},{"inputs":[],"name":"NotPaused","type":"error"},{"inputs":[],"name":"NotWhitelisted","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"recipient","type":"bytes"},{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"}],"name":"Deposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"asset","type":"address"}],"name":"Unwhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"asset","type":"address"}],"name":"Whitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[],"name":"TSSAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TSSAddressUpdater","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"recipient","type":"bytes"},{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"message","type":"bytes"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceTSSAddressUpdater","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"unwhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"updateTSSAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"whitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]` ) +// GetConnectorABI returns the ABI of the connector contract func GetConnectorABI() string { return ConnectorAbiString } +// GetERC20CustodyABI returns the ABI of the erc20 custody contract func GetERC20CustodyABI() string { return ERC20CustodyAbiString } +// New returns a new config +// It is initialize with default chain configs func New() Config { return Config{ EVMChainConfigs: evmChainsConfigs, @@ -28,6 +37,7 @@ func New() Config { } } +// bitcoinConfigRegnet contains Bitcoin config for regnet var bitcoinConfigRegnet = BTCConfig{ RPCUsername: "smoketest", // smoketest is the previous name for E2E test, we keep this name for compatibility between client versions in upgrade test RPCPassword: "123", @@ -35,6 +45,8 @@ var bitcoinConfigRegnet = BTCConfig{ RPCParams: "regtest", } +// evmChainsConfigs contains EVM chain configs +// it contains list of EVM chains with empty endpoint except for localnet var evmChainsConfigs = map[int64]EVMConfig{ chains.Ethereum.ChainId: { Chain: chains.Ethereum, diff --git a/zetaclient/config/types.go b/zetaclient/config/types.go index b14cc8191b..96cdf24a4c 100644 --- a/zetaclient/config/types.go +++ b/zetaclient/config/types.go @@ -12,9 +12,14 @@ import ( type KeyringBackend string const ( + // KeyringBackendUndefined is undefined keyring backend KeyringBackendUndefined KeyringBackend = "" - KeyringBackendTest KeyringBackend = "test" - KeyringBackendFile KeyringBackend = "file" + + // KeyringBackendTest is the test Cosmos keyring backend + KeyringBackendTest KeyringBackend = "test" + + // KeyringBackendFile is the file Cosmos keyring backend + KeyringBackendFile KeyringBackend = "file" ) // ClientConfiguration is a subset of zetaclient config that is used by zetacore client @@ -27,11 +32,13 @@ type ClientConfiguration struct { HsmMode bool `json:"hsm_mode"` } +// EVMConfig is the config for EVM chain type EVMConfig struct { Chain chains.Chain Endpoint string } +// BTCConfig is the config for Bitcoin chain type BTCConfig struct { // the following are rpcclient ConnConfig fields RPCUsername string @@ -40,6 +47,7 @@ type BTCConfig struct { RPCParams string // "regtest", "mainnet", "testnet3" } +// ComplianceConfig is the config for compliance type ComplianceConfig struct { LogPath string `json:"LogPath"` RestrictedAddresses []string `json:"RestrictedAddresses"` @@ -78,6 +86,8 @@ type Config struct { ComplianceConfig ComplianceConfig `json:"ComplianceConfig"` } +// NewConfig returns a new Config with initialize EVM chain mapping and a new mutex +// TODO(revamp): consolidate with New function func NewConfig() Config { return Config{ cfgLock: &sync.RWMutex{}, @@ -85,6 +95,7 @@ func NewConfig() Config { } } +// GetEVMConfig returns the EVM config for the given chain ID func (c Config) GetEVMConfig(chainID int64) (EVMConfig, bool) { c.cfgLock.RLock() defer c.cfgLock.RUnlock() @@ -92,6 +103,7 @@ func (c Config) GetEVMConfig(chainID int64) (EVMConfig, bool) { return evmCfg, found } +// GetAllEVMConfigs returns a map of all EVM configs func (c Config) GetAllEVMConfigs() map[int64]EVMConfig { c.cfgLock.RLock() defer c.cfgLock.RUnlock() @@ -104,6 +116,7 @@ func (c Config) GetAllEVMConfigs() map[int64]EVMConfig { return copied } +// GetBTCConfig returns the BTC config func (c Config) GetBTCConfig() (BTCConfig, bool) { c.cfgLock.RLock() defer c.cfgLock.RUnlock() @@ -111,6 +124,7 @@ func (c Config) GetBTCConfig() (BTCConfig, bool) { return c.BitcoinConfig, c.BitcoinConfig != (BTCConfig{}) } +// String returns the string representation of the config func (c Config) String() string { s, err := json.MarshalIndent(c, "", "\t") if err != nil { @@ -131,6 +145,7 @@ func (c Config) GetRestrictedAddressBook() map[string]bool { return restrictedAddresses } +// GetKeyringBackend returns the keyring backend func (c *Config) GetKeyringBackend() KeyringBackend { c.cfgLock.RLock() defer c.cfgLock.RUnlock() From ddc0f1a5ea0d96f21818c681ede4a7a01d245edc Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 5 Jun 2024 14:52:20 +0200 Subject: [PATCH 05/16] keys and metrics --- zetaclient/context/app_context.go | 2 ++ zetaclient/context/zetacore_context.go | 5 +++++ zetaclient/hsm/hsm_signer.go | 3 +++ zetaclient/keys/keys.go | 7 ++++++- zetaclient/metrics/metrics.go | 17 +++++++++++++++++ zetaclient/metrics/telemetry.go | 7 +++++++ 6 files changed, 40 insertions(+), 1 deletion(-) diff --git a/zetaclient/context/app_context.go b/zetaclient/context/app_context.go index d47cd925e8..01ed9c565a 100644 --- a/zetaclient/context/app_context.go +++ b/zetaclient/context/app_context.go @@ -22,10 +22,12 @@ func NewAppContext( } } +// Config returns the config of the app func (a AppContext) Config() config.Config { return a.config } +// ZetacoreContext returns the context for ZetaChain func (a AppContext) ZetacoreContext() *ZetacoreContext { return a.coreContext } diff --git a/zetaclient/context/zetacore_context.go b/zetaclient/context/zetacore_context.go index 73ad83ff29..17d4cc5c3d 100644 --- a/zetaclient/context/zetacore_context.go +++ b/zetaclient/context/zetacore_context.go @@ -52,6 +52,7 @@ func NewZetacoreContext(cfg config.Config) *ZetacoreContext { } } +// GetKeygen returns the current keygen func (c *ZetacoreContext) GetKeygen() observertypes.Keygen { c.coreContextLock.RLock() defer c.coreContextLock.RUnlock() @@ -69,6 +70,7 @@ func (c *ZetacoreContext) GetKeygen() observertypes.Keygen { } } +// GetCurrentTssPubkey returns the current tss pubkey func (c *ZetacoreContext) GetCurrentTssPubkey() string { c.coreContextLock.RLock() defer c.coreContextLock.RUnlock() @@ -99,6 +101,7 @@ func (c *ZetacoreContext) GetEnabledExternalChains() []chains.Chain { return externalChains } +// GetEVMChainParams returns chain params for a specific EVM chain func (c *ZetacoreContext) GetEVMChainParams(chainID int64) (*observertypes.ChainParams, bool) { c.coreContextLock.RLock() defer c.coreContextLock.RUnlock() @@ -107,6 +110,7 @@ func (c *ZetacoreContext) GetEVMChainParams(chainID int64) (*observertypes.Chain return evmChainParams, found } +// GetAllEVMChainParams returns all chain params for EVM chains func (c *ZetacoreContext) GetAllEVMChainParams() map[int64]*observertypes.ChainParams { c.coreContextLock.RLock() defer c.coreContextLock.RUnlock() @@ -137,6 +141,7 @@ func (c *ZetacoreContext) GetBTCChainParams() (chains.Chain, *observertypes.Chai return *chain, c.bitcoinChainParams, true } +// GetCrossChainFlags returns crosschain flags func (c *ZetacoreContext) GetCrossChainFlags() observertypes.CrosschainFlags { c.coreContextLock.RLock() defer c.coreContextLock.RUnlock() diff --git a/zetaclient/hsm/hsm_signer.go b/zetaclient/hsm/hsm_signer.go index a6d513a353..7d11952716 100644 --- a/zetaclient/hsm/hsm_signer.go +++ b/zetaclient/hsm/hsm_signer.go @@ -1,3 +1,5 @@ +// Package hsm is used to interact with chains with a HSM +// it is currently not used package hsm import ( @@ -158,6 +160,7 @@ func SignWithHSM( return txBuilder.SetSignatures(prevSignatures...) } +// GetPKCS11Config returns the PKCS11 configuration from the environment variables func GetPKCS11Config() (config *crypto11.Config, err error) { config = &crypto11.Config{} config.Path = os.Getenv(hsmPath) diff --git a/zetaclient/keys/keys.go b/zetaclient/keys/keys.go index 3532c12233..0fdef6c204 100644 --- a/zetaclient/keys/keys.go +++ b/zetaclient/keys/keys.go @@ -23,8 +23,11 @@ import ( ) var ( + // ErrBech32ifyPubKey is an error when Bech32ifyPubKey fails ErrBech32ifyPubKey = errors.New("Bech32ifyPubKey fail in main") - ErrNewPubKey = errors.New("NewPubKey error from string") + + // ErrNewPubKey is an error when NewPubKey fails + ErrNewPubKey = errors.New("NewPubKey error from string") ) var _ interfaces.ObserverKeys = &Keys{} @@ -52,6 +55,7 @@ func NewKeysWithKeybase( } } +// GetGranteeKeyName return the grantee name func GetGranteeKeyName(signerName string) string { return signerName } @@ -110,6 +114,7 @@ func (k *Keys) GetSignerInfo() *ckeys.Record { return info } +// GetOperatorAddress return the operator address func (k *Keys) GetOperatorAddress() sdk.AccAddress { return k.OperatorAddress } diff --git a/zetaclient/metrics/metrics.go b/zetaclient/metrics/metrics.go index 1170d16f68..4c7f5ff06b 100644 --- a/zetaclient/metrics/metrics.go +++ b/zetaclient/metrics/metrics.go @@ -11,79 +11,93 @@ import ( "github.com/rs/zerolog/log" ) +// Metrics is a struct that contains the http server for metrics type Metrics struct { s *http.Server } +// ZetaClientNamespace is the namespace for the metrics const ZetaClientNamespace = "zetaclient" var ( + // PendingTxsPerChain is a gauge that contains the number of pending transactions per chain PendingTxsPerChain = promauto.NewGaugeVec(prometheus.GaugeOpts{ Namespace: ZetaClientNamespace, Name: "pending_txs_total", Help: "Number of pending transactions per chain", }, []string{"chain"}) + // GetFilterLogsPerChain is a counter that contains the number of getLogs per chain GetFilterLogsPerChain = promauto.NewCounterVec(prometheus.CounterOpts{ Namespace: ZetaClientNamespace, Name: "rpc_getFilterLogs_count", Help: "Count of getLogs per chain", }, []string{"chain"}) + // GetBlockByNumberPerChain is a counter that contains the number of getBlockByNumber per chain GetBlockByNumberPerChain = promauto.NewCounterVec(prometheus.CounterOpts{ Namespace: ZetaClientNamespace, Name: "rpc_getBlockByNumber_count", Help: "Count of getLogs per chain", }, []string{"chain"}) + // TssNodeBlamePerPubKey is a counter that contains the number of tss node blame per pubkey TssNodeBlamePerPubKey = promauto.NewCounterVec(prometheus.CounterOpts{ Namespace: ZetaClientNamespace, Name: "tss_node_blame_count", Help: "Tss node blame counter per pubkey", }, []string{"pubkey"}) + // HotKeyBurnRate is a gauge that contains the fee burn rate of the hotkey HotKeyBurnRate = promauto.NewGauge(prometheus.GaugeOpts{ Namespace: ZetaClientNamespace, Name: "hotkey_burn_rate", Help: "Fee burn rate of the hotkey", }) + // NumberOfUTXO is a gauge that contains the number of UTXOs NumberOfUTXO = promauto.NewGauge(prometheus.GaugeOpts{ Namespace: ZetaClientNamespace, Name: "utxo_number", Help: "Number of UTXOs", }) + // LastScannedBlockNumber is a gauge that contains the last scanned block number per chain LastScannedBlockNumber = promauto.NewGaugeVec(prometheus.GaugeOpts{ Namespace: ZetaClientNamespace, Name: "last_scanned_block_number", Help: "Last scanned block number per chain", }, []string{"chain"}) + // LastCoreBlockNumber is a gauge that contains the last core block number LastCoreBlockNumber = promauto.NewGauge(prometheus.GaugeOpts{ Namespace: ZetaClientNamespace, Name: "last_core_block_number", Help: "Last core block number", }) + // Info is a gauge that contains information about the zetaclient environment Info = promauto.NewGaugeVec(prometheus.GaugeOpts{ Namespace: ZetaClientNamespace, Name: "info", Help: "Information about Zetaclient environment", }, []string{"version"}) + // LastStartTime is a gauge that contains the start time in Unix time LastStartTime = promauto.NewGauge(prometheus.GaugeOpts{ Namespace: ZetaClientNamespace, Name: "last_start_timestamp_seconds", Help: "Start time in Unix time", }) + // NumActiveMsgSigns is a gauge that contains the number of concurrent key signs NumActiveMsgSigns = promauto.NewGauge(prometheus.GaugeOpts{ Namespace: ZetaClientNamespace, Name: "num_active_message_signs", Help: "Number of concurrent key signs", }) + // PercentageOfRateReached is a gauge that contains the percentage of the rate limiter rate reached PercentageOfRateReached = promauto.NewGauge(prometheus.GaugeOpts{ Namespace: ZetaClientNamespace, Name: "percentage_of_rate_reached", @@ -91,6 +105,7 @@ var ( }) ) +// NewMetrics creates a new Metrics instance func NewMetrics() (*Metrics, error) { handler := promhttp.InstrumentMetricHandler( prometheus.DefaultRegisterer, @@ -111,6 +126,7 @@ func NewMetrics() (*Metrics, error) { }, nil } +// Start starts the metrics server func (m *Metrics) Start() { log.Info().Msg("metrics server starting") go func() { @@ -120,6 +136,7 @@ func (m *Metrics) Start() { }() } +// Stop stops the metrics server func (m *Metrics) Stop() error { ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) defer cancel() diff --git a/zetaclient/metrics/telemetry.go b/zetaclient/metrics/telemetry.go index bdedbd9c50..42638904e5 100644 --- a/zetaclient/metrics/telemetry.go +++ b/zetaclient/metrics/telemetry.go @@ -90,6 +90,7 @@ func (t *TelemetryServer) Handlers() http.Handler { return router } +// Start starts the telemetry server func (t *TelemetryServer) Start() error { if t.s == nil { return errors.New("invalid http server instance") @@ -103,6 +104,7 @@ func (t *TelemetryServer) Start() error { return nil } +// Stop stops the telemetry server func (t *TelemetryServer) Stop() error { c, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() @@ -113,10 +115,12 @@ func (t *TelemetryServer) Stop() error { return err } +// pingHandler returns a 200 OK response func (t *TelemetryServer) pingHandler(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) } +// p2pHandler returns the p2p id func (t *TelemetryServer) p2pHandler(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) t.mu.Lock() @@ -124,6 +128,7 @@ func (t *TelemetryServer) p2pHandler(w http.ResponseWriter, _ *http.Request) { fmt.Fprintf(w, "%s", t.p2pid) } +// ipHandler returns the ip address func (t *TelemetryServer) ipHandler(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) t.mu.Lock() @@ -131,6 +136,7 @@ func (t *TelemetryServer) ipHandler(w http.ResponseWriter, _ *http.Request) { fmt.Fprintf(w, "%s", t.ipAddress) } +// hotKeyFeeBurnRate returns the hot key fee burn rate func (t *TelemetryServer) hotKeyFeeBurnRate(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) t.mu.Lock() @@ -138,6 +144,7 @@ func (t *TelemetryServer) hotKeyFeeBurnRate(w http.ResponseWriter, _ *http.Reque fmt.Fprintf(w, "%v", t.HotKeyBurnRate.GetBurnRate()) } +// logMiddleware logs the incoming HTTP request func logMiddleware() mux.MiddlewareFunc { return func(handler http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { From 0f8bda92988b68d4d73180a3dfbf4e53dfa894d7 Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 5 Jun 2024 15:10:08 +0200 Subject: [PATCH 06/16] orchestrator and tss --- zetaclient/orchestrator/orchestrator.go | 10 +++++++-- .../outbound_processor_manager.go | 8 +++++++ zetaclient/supplychecker/logger.go | 1 + zetaclient/supplychecker/validate.go | 1 + .../supplychecker/zeta_supply_checker.go | 6 +++++ zetaclient/testutils/mempool_client.go | 6 +++++ zetaclient/testutils/testdata.go | 2 ++ zetaclient/tss/tss_signer.go | 22 +++++++++++++++++++ 8 files changed, 54 insertions(+), 2 deletions(-) diff --git a/zetaclient/orchestrator/orchestrator.go b/zetaclient/orchestrator/orchestrator.go index f9678301ff..dbba673641 100644 --- a/zetaclient/orchestrator/orchestrator.go +++ b/zetaclient/orchestrator/orchestrator.go @@ -32,6 +32,8 @@ const ( loggerSamplingRate = 10 ) +// Log is a struct that contains the logger +// TODO(revamp): rename to logger type Log struct { Std zerolog.Logger Sampled zerolog.Logger @@ -42,8 +44,10 @@ type Orchestrator struct { // zetacore client zetacoreClient interfaces.ZetacoreClient - // chain signers and observers - signerMap map[int64]interfaces.ChainSigner + // signerMap contains the chain signers indexed by chainID + signerMap map[int64]interfaces.ChainSigner + + // observerMap contains the chain observers indexed by chainID observerMap map[int64]interfaces.ChainObserver // outbound processor @@ -94,6 +98,7 @@ func NewOrchestrator( return &oc } +// MonitorCore starts the orchestrator for CCTXs func (oc *Orchestrator) MonitorCore(appContext *context.AppContext) error { signerAddress, err := oc.zetacoreClient.GetKeys().GetAddress() if err != nil { @@ -231,6 +236,7 @@ func (oc *Orchestrator) GetPendingCctxsWithinRatelimit( } // StartCctxScheduler schedules keysigns for cctxs on each ZetaChain block (the ticker) +// TODO(revamp): make this function simpler func (oc *Orchestrator) StartCctxScheduler(appContext *context.AppContext) { observeTicker := time.NewTicker(3 * time.Second) var lastBlockNum int64 diff --git a/zetaclient/outboundprocessor/outbound_processor_manager.go b/zetaclient/outboundprocessor/outbound_processor_manager.go index 8499252ede..367c2698ea 100644 --- a/zetaclient/outboundprocessor/outbound_processor_manager.go +++ b/zetaclient/outboundprocessor/outbound_processor_manager.go @@ -8,6 +8,9 @@ import ( "github.com/rs/zerolog" ) +// Processor is a struct that contains data about outbound being processed +// TODO(revamp): rename this struct as it is not used to process outbound but track their processing +// We can also consider removing it once we refactor chain client to contains common logic to sign outbounds type Processor struct { outboundStartTime map[string]time.Time outboundEndTime map[string]time.Time @@ -17,6 +20,7 @@ type Processor struct { numActiveProcessor int64 } +// NewProcessor creates a new Processor func NewProcessor(logger zerolog.Logger) *Processor { return &Processor{ outboundStartTime: make(map[string]time.Time), @@ -28,6 +32,7 @@ func NewProcessor(logger zerolog.Logger) *Processor { } } +// StartTryProcess register a new outbound ID to track func (p *Processor) StartTryProcess(outboundID string) { p.mu.Lock() defer p.mu.Unlock() @@ -37,6 +42,7 @@ func (p *Processor) StartTryProcess(outboundID string) { p.Logger.Info().Msgf("StartTryProcess %s, numActiveProcessor %d", outboundID, p.numActiveProcessor) } +// EndTryProcess remove the outbound ID from tracking func (p *Processor) EndTryProcess(outboundID string) { p.mu.Lock() defer p.mu.Unlock() @@ -47,6 +53,7 @@ func (p *Processor) EndTryProcess(outboundID string) { Msgf("EndTryProcess %s, numActiveProcessor %d, time elapsed %s", outboundID, p.numActiveProcessor, time.Since(p.outboundStartTime[outboundID])) } +// IsOutboundActive checks if the outbound ID is being processed func (p *Processor) IsOutboundActive(outboundID string) bool { p.mu.Lock() defer p.mu.Unlock() @@ -54,6 +61,7 @@ func (p *Processor) IsOutboundActive(outboundID string) bool { return found } +// TimeInTryProcess returns the time elapsed since the outbound ID is being processed func (p *Processor) TimeInTryProcess(outboundID string) time.Duration { p.mu.Lock() defer p.mu.Unlock() diff --git a/zetaclient/supplychecker/logger.go b/zetaclient/supplychecker/logger.go index 223e43eab8..89da0300d6 100644 --- a/zetaclient/supplychecker/logger.go +++ b/zetaclient/supplychecker/logger.go @@ -21,6 +21,7 @@ type ZetaSupplyCheckLogs struct { SupplyCheckSuccess bool `json:"supply_check_success"` } +// LogOutput logs the output of the ZetaSupplyChecker func (z ZetaSupplyCheckLogs) LogOutput() { output, err := bitcoin.PrettyPrintStruct(z) if err != nil { diff --git a/zetaclient/supplychecker/validate.go b/zetaclient/supplychecker/validate.go index d70bda8c34..f9e4dbaf79 100644 --- a/zetaclient/supplychecker/validate.go +++ b/zetaclient/supplychecker/validate.go @@ -5,6 +5,7 @@ import ( "github.com/rs/zerolog" ) +// ValidateZetaSupply validates the zeta supply from the checked values func ValidateZetaSupply( logger zerolog.Logger, abortedTxAmounts, zetaInTransit, genesisAmounts, externalChainTotalSupply, zetaTokenSupplyOnNode, ethLockedAmount sdkmath.Int, diff --git a/zetaclient/supplychecker/zeta_supply_checker.go b/zetaclient/supplychecker/zeta_supply_checker.go index f975c7eb88..94b92849ed 100644 --- a/zetaclient/supplychecker/zeta_supply_checker.go +++ b/zetaclient/supplychecker/zeta_supply_checker.go @@ -92,6 +92,7 @@ func NewZetaSupplyChecker( return zetaSupplyChecker, nil } +// Start starts the ZetaSupplyChecker func (zs *ZetaSupplyChecker) Start() { defer zs.ticker.Stop() for { @@ -107,11 +108,13 @@ func (zs *ZetaSupplyChecker) Start() { } } +// Stop stops the ZetaSupplyChecker func (zs *ZetaSupplyChecker) Stop() { zs.logger.Info().Msgf("ZetaSupplyChecker is stopping") close(zs.stop) } +// CheckZetaTokenSupply checks the total supply of Zeta tokens func (zs *ZetaSupplyChecker) CheckZetaTokenSupply() error { externalChainTotalSupply := sdkmath.ZeroInt() @@ -194,6 +197,7 @@ func (zs *ZetaSupplyChecker) CheckZetaTokenSupply() error { return nil } +// AbortedTxAmount returns the amount of Zeta tokens in aborted transactions func (zs *ZetaSupplyChecker) AbortedTxAmount() (sdkmath.Int, error) { amount, err := zs.zetaClient.GetAbortedZetaAmount() if err != nil { @@ -206,6 +210,7 @@ func (zs *ZetaSupplyChecker) AbortedTxAmount() (sdkmath.Int, error) { return amountInt, nil } +// GetAmountOfZetaInTransit returns the amount of Zeta tokens in transit func (zs *ZetaSupplyChecker) GetAmountOfZetaInTransit() (sdkmath.Int, error) { chainsToCheck := make([]chains.Chain, len(zs.externalEvmChain)+1) chainsToCheck = append(append(chainsToCheck, zs.externalEvmChain...), zs.ethereumChain) @@ -223,6 +228,7 @@ func (zs *ZetaSupplyChecker) GetAmountOfZetaInTransit() (sdkmath.Int, error) { return amountInt, nil } +// GetPendingCCTXInTransit returns the pending CCTX in transit func (zs *ZetaSupplyChecker) GetPendingCCTXInTransit(receivingChains []chains.Chain) []*types.CrossChainTx { cctxInTransit := make([]*types.CrossChainTx, 0) for _, chain := range receivingChains { diff --git a/zetaclient/testutils/mempool_client.go b/zetaclient/testutils/mempool_client.go index 03c79120dc..a49ff45e78 100644 --- a/zetaclient/testutils/mempool_client.go +++ b/zetaclient/testutils/mempool_client.go @@ -15,6 +15,7 @@ const ( APIURLBlockTxsTestnet = "https://mempool.space/testnet/api/block/%s/txs" ) +// MempoolBlock represents a block in the mempool type MempoolBlock struct { ID string `json:"id"` Height int `json:"height"` @@ -32,6 +33,7 @@ type MempoolBlock struct { Extras BlockExtra `json:"extras"` } +// Vin represents a Bitcoin transaction input type Vin struct { TxID string `json:"txid"` Vout uint32 `json:"vout"` @@ -47,6 +49,7 @@ type Vin struct { Sequence uint32 `json:"sequence"` } +// Vout represents a Bitcoin transaction output type Vout struct { Scriptpubkey string `json:"scriptpubkey"` ScriptpubkeyAsm string `json:"scriptpubkey_asm"` @@ -54,6 +57,7 @@ type Vout struct { Value int64 `json:"value"` } +// MempoolTx represents a transaction in the mempool type MempoolTx struct { TxID string `json:"txid"` Version int `json:"version"` @@ -65,6 +69,7 @@ type MempoolTx struct { Fee int `json:"fee"` } +// BlockExtra represents extra information about a block type BlockExtra struct { TotalFees int `json:"totalFees"` MedianFee float64 `json:"medianFee"` @@ -105,6 +110,7 @@ type BlockExtra struct { ExpectedWeight int `json:"expectedWeight"` } +// Get makes a GET request to the given path and decodes the response func Get(ctx context.Context, path string, v interface{}) error { req, err := http.NewRequest("GET", path, nil) if err != nil { diff --git a/zetaclient/testutils/testdata.go b/zetaclient/testutils/testdata.go index fc028bf0ec..620eb16b17 100644 --- a/zetaclient/testutils/testdata.go +++ b/zetaclient/testutils/testdata.go @@ -48,6 +48,8 @@ func LoadObjectFromJSONFile(t *testing.T, obj interface{}, filename string) { require.NoError(t, err) } +// ComplianceConfigTest returns a test compliance config +// TODO(revamp): move to sample package func ComplianceConfigTest() config.ComplianceConfig { return config.ComplianceConfig{ RestrictedAddresses: []string{RestrictedEVMAddressTest, RestrictedBtcAddressTest}, diff --git a/zetaclient/tss/tss_signer.go b/zetaclient/tss/tss_signer.go index 2915dd6d0a..661a3f6228 100644 --- a/zetaclient/tss/tss_signer.go +++ b/zetaclient/tss/tss_signer.go @@ -37,15 +37,18 @@ import ( ) const ( + // envFlagPostBlame is the environment flag to enable posting blame data to core envFlagPostBlame = "POST_BLAME" ) +// Key is a struct that holds the public key, bech32 pubkey, and address for the TSS type Key struct { PubkeyInBytes []byte PubkeyInBech32 string AddressInHex string } +// NewTSSKey creates a new TSS key func NewTSSKey(pk string) (*Key, error) { TSSKey := &Key{ PubkeyInBech32: pk, @@ -141,6 +144,8 @@ func NewTSS( return &newTss, nil } +// SetupTSSServer creates a new TSS server +// TODO(revamp): move to TSS server file func SetupTSSServer( peer p2p.AddrList, privkey tmcrypto.PrivKey, @@ -207,6 +212,7 @@ func SetupTSSServer( return tssServer, nil } +// Pubkey returns the current pubkey func (tss *TSS) Pubkey() []byte { return tss.Keys[tss.CurrentPubkey].PubkeyInBytes } @@ -404,6 +410,7 @@ func (tss *TSS) SignBatch(digests [][]byte, height uint64, nonce uint64, chain * return sigBytes, nil } +// Validate validates the TSS func (tss *TSS) Validate() error { evmAddress := tss.EVMAddress() blankAddress := ethcommon.Address{} @@ -419,6 +426,7 @@ func (tss *TSS) Validate() error { return nil } +// EVMAddress generates an EVM address from pubkey func (tss *TSS) EVMAddress() ethcommon.Address { addr, err := GetTssAddrEVM(tss.CurrentPubkey) if err != nil { @@ -438,6 +446,7 @@ func (tss *TSS) BTCAddress() string { return addr } +// BTCAddressWitnessPubkeyHash generates a bech32 p2wpkh address from pubkey func (tss *TSS) BTCAddressWitnessPubkeyHash() *btcutil.AddressWitnessPubKeyHash { addrWPKH, err := getKeyAddrBTCWitnessPubkeyHash(tss.CurrentPubkey, tss.BitcoinChainID) if err != nil { @@ -447,6 +456,7 @@ func (tss *TSS) BTCAddressWitnessPubkeyHash() *btcutil.AddressWitnessPubKeyHash return addrWPKH } +// PubKeyCompressedBytes returns the compressed bytes of the current pubkey func (tss *TSS) PubKeyCompressedBytes() []byte { pubk, err := cosmos.GetPubKeyFromBech32(cosmos.Bech32PubKeyTypeAccPub, tss.CurrentPubkey) if err != nil { @@ -466,6 +476,7 @@ func (tss *TSS) InsertPubKey(pk string) error { return nil } +// VerifyKeysharesForPubkeys verifies the keyshares for the pubkeys func (tss *TSS) VerifyKeysharesForPubkeys(tssList []observertypes.TSS, granteePubKey32 string) error { for _, t := range tssList { if wasNodePartOfTss(granteePubKey32, t.TssParticipantList) { @@ -477,6 +488,7 @@ func (tss *TSS) VerifyKeysharesForPubkeys(tssList []observertypes.TSS, granteePu return nil } +// LoadTssFilesFromDirectory loads the TSS files from the directory func (tss *TSS) LoadTssFilesFromDirectory(tssPath string) error { files, err := os.ReadDir(tssPath) if err != nil { @@ -528,6 +540,7 @@ func (tss *TSS) LoadTssFilesFromDirectory(tssPath string) error { return nil } +// GetTssAddrBTC generates a bech32 p2wpkh address from pubkey func GetTssAddrBTC(tssPubkey string, bitcoinChainID int64) (string, error) { addrWPKH, err := getKeyAddrBTCWitnessPubkeyHash(tssPubkey, bitcoinChainID) if err != nil { @@ -538,6 +551,7 @@ func GetTssAddrBTC(tssPubkey string, bitcoinChainID int64) (string, error) { return addrWPKH.EncodeAddress(), nil } +// GetTssAddrEVM generates an EVM address from pubkey func GetTssAddrEVM(tssPubkey string) (ethcommon.Address, error) { var keyAddr ethcommon.Address pubk, err := cosmos.GetPubKeyFromBech32(cosmos.Bech32PubKeyTypeAccPub, tssPubkey) @@ -558,6 +572,8 @@ func GetTssAddrEVM(tssPubkey string) (ethcommon.Address, error) { return keyAddr, nil } +// TestKeysign tests the keysign +// TODO(revamp): move to a test package func TestKeysign(tssPubkey string, tssServer *tss.TssServer) error { log.Info().Msg("trying keysign...") data := []byte("hello meta") @@ -594,11 +610,14 @@ func TestKeysign(tssPubkey string, tssServer *tss.TssServer) error { return fmt.Errorf("verify signature fail") } +// IsEnvFlagEnabled checks if the environment flag is enabled func IsEnvFlagEnabled(flag string) bool { value := os.Getenv(flag) return value == "true" || value == "1" } +// verifySignature verifies the signature +// TODO(revamp): move to a test package func verifySignature(tssPubkey string, signature []keysign.Signature, H []byte) bool { if len(signature) == 0 { log.Warn().Msg("verify_signature: empty signature array") @@ -640,12 +659,14 @@ func verifySignature(tssPubkey string, signature []keysign.Signature, H []byte) return bytes.Equal(pubkey.Bytes(), compressedPubkey) } +// combineDigests combines the digests func combineDigests(digestList []string) []byte { digestConcat := strings.Join(digestList[:], "") digestBytes := chainhash.DoubleHashH([]byte(digestConcat)) return digestBytes.CloneBytes() } +// wasNodePartOfTss checks if the node was part of the TSS func wasNodePartOfTss(granteePubKey32 string, granteeList []string) bool { for _, grantee := range granteeList { if granteePubKey32 == grantee { @@ -655,6 +676,7 @@ func wasNodePartOfTss(granteePubKey32 string, granteeList []string) bool { return false } +// getKeyAddrBTCWitnessPubkeyHash generates a bech32 p2wpkh address from pubkey func getKeyAddrBTCWitnessPubkeyHash(tssPubkey string, chainID int64) (*btcutil.AddressWitnessPubKeyHash, error) { pubk, err := cosmos.GetPubKeyFromBech32(cosmos.Bech32PubKeyTypeAccPub, tssPubkey) if err != nil { From 9a0ff288923bbbb829e02695fa2287bd805aef53 Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 5 Jun 2024 15:22:42 +0200 Subject: [PATCH 07/16] zetacore package --- zetaclient/types/dynamic_ticker.go | 5 ++++ zetaclient/types/ethish.go | 1 + zetaclient/types/sql_evm.go | 7 ++++++ zetaclient/zetacore/broadcast.go | 3 ++- zetaclient/zetacore/client.go | 4 +++ zetaclient/zetacore/query.go | 39 ++++++++++++++++++++++++++++++ zetaclient/zetacore/tx.go | 17 +++++++++++++ 7 files changed, 75 insertions(+), 1 deletion(-) diff --git a/zetaclient/types/dynamic_ticker.go b/zetaclient/types/dynamic_ticker.go index 49434e03ea..103bfffb94 100644 --- a/zetaclient/types/dynamic_ticker.go +++ b/zetaclient/types/dynamic_ticker.go @@ -7,12 +7,14 @@ import ( "github.com/rs/zerolog" ) +// DynamicTicker is a ticker that can have its interval updated type DynamicTicker struct { name string interval uint64 impl *time.Ticker } +// NewDynamicTicker creates a new DynamicTicker func NewDynamicTicker(name string, interval uint64) (*DynamicTicker, error) { if interval <= 0 { return nil, fmt.Errorf("non-positive ticker interval %d for %s", interval, name) @@ -25,10 +27,12 @@ func NewDynamicTicker(name string, interval uint64) (*DynamicTicker, error) { }, nil } +// C returns the channel of the ticker func (t *DynamicTicker) C() <-chan time.Time { return t.impl.C } +// UpdateInterval updates the interval of the ticker func (t *DynamicTicker) UpdateInterval(newInterval uint64, logger zerolog.Logger) { if newInterval > 0 && t.interval != newInterval { t.impl.Stop() @@ -39,6 +43,7 @@ func (t *DynamicTicker) UpdateInterval(newInterval uint64, logger zerolog.Logger } } +// Stop stops the ticker func (t *DynamicTicker) Stop() { t.impl.Stop() } diff --git a/zetaclient/types/ethish.go b/zetaclient/types/ethish.go index fd3a40af6d..6935a22141 100644 --- a/zetaclient/types/ethish.go +++ b/zetaclient/types/ethish.go @@ -4,6 +4,7 @@ import ( "encoding/hex" ) +// EthHexToBytes converts an Ethereum hex string to bytes func BytesToEthHex(b []byte) string { return "0x" + hex.EncodeToString(b) } diff --git a/zetaclient/types/sql_evm.go b/zetaclient/types/sql_evm.go index c551fda503..398a968a60 100644 --- a/zetaclient/types/sql_evm.go +++ b/zetaclient/types/sql_evm.go @@ -71,6 +71,7 @@ type LastBlockSQLType struct { // Type translation functions: +// ToReceiptDBType : Converts an Ethereum receipt to a ReceiptDB type func ToReceiptDBType(receipt *ethtypes.Receipt) (ReceiptDB, error) { logs, err := json.Marshal(receipt.Logs) if err != nil { @@ -92,6 +93,7 @@ func ToReceiptDBType(receipt *ethtypes.Receipt) (ReceiptDB, error) { }, nil } +// FromReceiptDBType : Converts a ReceiptDB type to an Ethereum receipt func FromReceiptDBType(receipt ReceiptDB) (*ethtypes.Receipt, error) { res := ðtypes.Receipt{ Type: receipt.Type, @@ -111,6 +113,7 @@ func FromReceiptDBType(receipt ReceiptDB) (*ethtypes.Receipt, error) { return res, err } +// ToReceiptSQLType : Converts an Ethereum receipt to a ReceiptSQLType func ToReceiptSQLType(receipt *ethtypes.Receipt, index string) (*ReceiptSQLType, error) { r, err := ToReceiptDBType(receipt) if err != nil { @@ -122,6 +125,7 @@ func ToReceiptSQLType(receipt *ethtypes.Receipt, index string) (*ReceiptSQLType, }, nil } +// ToTransactionDBType : Converts an Ethereum transaction to a TransactionDB type func ToTransactionDBType(transaction *ethtypes.Transaction) (TransactionDB, error) { data, err := transaction.MarshalBinary() if err != nil { @@ -137,12 +141,14 @@ func ToTransactionDBType(transaction *ethtypes.Transaction) (TransactionDB, erro }, nil } +// FromTransactionDBType : Converts a TransactionDB type to an Ethereum transaction func FromTransactionDBType(transaction TransactionDB) (*ethtypes.Transaction, error) { res := ðtypes.Transaction{} err := res.UnmarshalBinary(transaction.TransactionData) return res, err } +// ToTransactionSQLType : Converts an Ethereum transaction to a TransactionSQLType func ToTransactionSQLType(transaction *ethtypes.Transaction, index string) (*TransactionSQLType, error) { trans, err := ToTransactionDBType(transaction) if err != nil { @@ -154,6 +160,7 @@ func ToTransactionSQLType(transaction *ethtypes.Transaction, index string) (*Tra }, nil } +// ToLastBlockSQLType : Converts a last block number to a LastBlockSQLType func ToLastBlockSQLType(lastBlock uint64) *LastBlockSQLType { return &LastBlockSQLType{ Model: gorm.Model{ID: LastBlockNumID}, diff --git a/zetaclient/zetacore/broadcast.go b/zetaclient/zetacore/broadcast.go index 82a011c6ba..6c1b475476 100644 --- a/zetaclient/zetacore/broadcast.go +++ b/zetaclient/zetacore/broadcast.go @@ -50,7 +50,7 @@ func BroadcastToZetaCore( return client.Broadcast(gasLimit, authzWrappedMsg, authzSigner) } -// Broadcast Broadcasts tx to metachain. Returns txHash and error +// Broadcast Broadcasts tx to ZetaChain. Returns txHash and error func (c *Client) Broadcast(gaslimit uint64, authzWrappedMsg sdktypes.Msg, authzSigner authz.Signer) (string, error) { c.broadcastLock.Lock() defer c.broadcastLock.Unlock() @@ -204,6 +204,7 @@ func (c *Client) GetContext() (client.Context, error) { return ctx, nil } +// SignTx signs a tx with the given name func (c *Client) SignTx( txf clienttx.Factory, name string, diff --git a/zetaclient/zetacore/client.go b/zetaclient/zetacore/client.go index d64fd56db1..f43117cd78 100644 --- a/zetaclient/zetacore/client.go +++ b/zetaclient/zetacore/client.go @@ -284,14 +284,18 @@ func (c *Client) UpdateZetacoreContext( return nil } +// Pause pauses the client func (c *Client) Pause() { <-c.pause } +// Unpause unpauses the client func (c *Client) Unpause() { c.pause <- struct{}{} } +// EnableMockSDKClient enables the mock cosmos sdk client +// TODO(revamp): move this to a test package func (c *Client) EnableMockSDKClient(client rpcclient.Client) { c.mockSDKClient = client c.enableMockSDKClient = true diff --git a/zetaclient/zetacore/query.go b/zetaclient/zetacore/query.go index b68ea37f8b..3c855039c6 100644 --- a/zetaclient/zetacore/query.go +++ b/zetaclient/zetacore/query.go @@ -25,6 +25,7 @@ import ( "github.com/zeta-chain/zetacore/zetaclient/chains/interfaces" ) +// GetCrosschainFlags returns the crosschain flags func (c *Client) GetCrosschainFlags() (observertypes.CrosschainFlags, error) { client := observertypes.NewQueryClient(c.grpcConn) resp, err := client.CrosschainFlags(context.Background(), &observertypes.QueryGetCrosschainFlagsRequest{}) @@ -34,6 +35,7 @@ func (c *Client) GetCrosschainFlags() (observertypes.CrosschainFlags, error) { return resp.CrosschainFlags, nil } +// GetBlockHeaderEnabledChains returns the enabled chains for block headers func (c *Client) GetBlockHeaderEnabledChains() ([]lightclienttypes.HeaderSupportedChain, error) { client := lightclienttypes.NewQueryClient(c.grpcConn) resp, err := client.HeaderEnabledChains(context.Background(), &lightclienttypes.QueryHeaderEnabledChainsRequest{}) @@ -43,6 +45,7 @@ func (c *Client) GetBlockHeaderEnabledChains() ([]lightclienttypes.HeaderSupport return resp.HeaderEnabledChains, nil } +// GetRateLimiterFlags returns the rate limiter flags func (c *Client) GetRateLimiterFlags() (crosschaintypes.RateLimiterFlags, error) { client := crosschaintypes.NewQueryClient(c.grpcConn) resp, err := client.RateLimiterFlags(context.Background(), &crosschaintypes.QueryRateLimiterFlagsRequest{}) @@ -52,6 +55,7 @@ func (c *Client) GetRateLimiterFlags() (crosschaintypes.RateLimiterFlags, error) return resp.RateLimiterFlags, nil } +// GetChainParamsForChainID returns the chain params for a given chain ID func (c *Client) GetChainParamsForChainID(externalChainID int64) (*observertypes.ChainParams, error) { client := observertypes.NewQueryClient(c.grpcConn) resp, err := client.GetChainParamsForChain( @@ -64,6 +68,7 @@ func (c *Client) GetChainParamsForChainID(externalChainID int64) (*observertypes return resp.ChainParams, nil } +// GetChainParams returns the chain params func (c *Client) GetChainParams() ([]*observertypes.ChainParams, error) { client := observertypes.NewQueryClient(c.grpcConn) var err error @@ -79,6 +84,7 @@ func (c *Client) GetChainParams() ([]*observertypes.ChainParams, error) { return nil, fmt.Errorf("failed to get chain params | err %s", err.Error()) } +// GetUpgradePlan returns the current upgrade plan func (c *Client) GetUpgradePlan() (*upgradetypes.Plan, error) { client := upgradetypes.NewQueryClient(c.grpcConn) @@ -89,6 +95,7 @@ func (c *Client) GetUpgradePlan() (*upgradetypes.Plan, error) { return resp.Plan, nil } +// GetAllCctx returns all cross chain transactions func (c *Client) GetAllCctx() ([]*crosschaintypes.CrossChainTx, error) { client := crosschaintypes.NewQueryClient(c.grpcConn) resp, err := client.CctxAll(context.Background(), &crosschaintypes.QueryAllCctxRequest{}) @@ -98,6 +105,7 @@ func (c *Client) GetAllCctx() ([]*crosschaintypes.CrossChainTx, error) { return resp.CrossChainTx, nil } +// GetCctxByHash returns a cross chain transaction by hash func (c *Client) GetCctxByHash(sendHash string) (*crosschaintypes.CrossChainTx, error) { client := crosschaintypes.NewQueryClient(c.grpcConn) resp, err := client.Cctx(context.Background(), &crosschaintypes.QueryGetCctxRequest{Index: sendHash}) @@ -107,6 +115,7 @@ func (c *Client) GetCctxByHash(sendHash string) (*crosschaintypes.CrossChainTx, return resp.CrossChainTx, nil } +// GetCctxByNonce returns a cross chain transaction by nonce func (c *Client) GetCctxByNonce(chainID int64, nonce uint64) (*crosschaintypes.CrossChainTx, error) { client := crosschaintypes.NewQueryClient(c.grpcConn) resp, err := client.CctxByNonce(context.Background(), &crosschaintypes.QueryGetCctxByNonceRequest{ @@ -119,6 +128,7 @@ func (c *Client) GetCctxByNonce(chainID int64, nonce uint64) (*crosschaintypes.C return resp.CrossChainTx, nil } +// GetObserverList returns the list of observers func (c *Client) GetObserverList() ([]string, error) { var err error client := observertypes.NewQueryClient(c.grpcConn) @@ -185,6 +195,7 @@ func (c *Client) ListPendingCctxWithinRatelimit() ([]*crosschaintypes.CrossChain return resp.CrossChainTx, resp.TotalPending, resp.CurrentWithdrawWindow, resp.CurrentWithdrawRate, resp.RateLimitExceeded, nil } +// GetAbortedZetaAmount returns the amount of zeta that has been aborted func (c *Client) GetAbortedZetaAmount() (string, error) { client := crosschaintypes.NewQueryClient(c.grpcConn) resp, err := client.ZetaAccounting(context.Background(), &crosschaintypes.QueryZetaAccountingRequest{}) @@ -194,6 +205,7 @@ func (c *Client) GetAbortedZetaAmount() (string, error) { return resp.AbortedZetaAmount, nil } +// GetGenesisSupply returns the genesis supply func (c *Client) GetGenesisSupply() (sdkmath.Int, error) { tmURL := fmt.Sprintf("http://%s", c.cfg.ChainRPC) s, err := tmhttp.New(tmURL, "/websocket") @@ -212,6 +224,7 @@ func (c *Client) GetGenesisSupply() (sdkmath.Int, error) { return bankstate.Supply.AmountOf(config.BaseDenom), nil } +// GetZetaTokenSupplyOnNode returns the zeta token supply on the node func (c *Client) GetZetaTokenSupplyOnNode() (sdkmath.Int, error) { client := banktypes.NewQueryClient(c.grpcConn) resp, err := client.SupplyOf(context.Background(), &banktypes.QuerySupplyOfRequest{Denom: config.BaseDenom}) @@ -221,6 +234,7 @@ func (c *Client) GetZetaTokenSupplyOnNode() (sdkmath.Int, error) { return resp.GetAmount().Amount, nil } +// GetLastBlockHeight returns the last block height func (c *Client) GetLastBlockHeight() ([]*crosschaintypes.LastBlockHeight, error) { client := crosschaintypes.NewQueryClient(c.grpcConn) resp, err := client.LastBlockHeightAll(context.Background(), &crosschaintypes.QueryAllLastBlockHeightRequest{}) @@ -231,6 +245,7 @@ func (c *Client) GetLastBlockHeight() ([]*crosschaintypes.LastBlockHeight, error return resp.LastBlockHeight, nil } +// GetLatestZetaBlock returns the latest zeta block func (c *Client) GetLatestZetaBlock() (*tmservice.Block, error) { client := tmservice.NewServiceClient(c.grpcConn) res, err := client.GetLatestBlock(context.Background(), &tmservice.GetLatestBlockRequest{}) @@ -240,6 +255,7 @@ func (c *Client) GetLatestZetaBlock() (*tmservice.Block, error) { return res.SdkBlock, nil } +// GetNodeInfo returns the node info func (c *Client) GetNodeInfo() (*tmservice.GetNodeInfoResponse, error) { var err error @@ -254,6 +270,7 @@ func (c *Client) GetNodeInfo() (*tmservice.GetNodeInfoResponse, error) { return nil, err } +// GetLastBlockHeightByChain returns the last block height by chain func (c *Client) GetLastBlockHeightByChain(chain chains.Chain) (*crosschaintypes.LastBlockHeight, error) { client := crosschaintypes.NewQueryClient(c.grpcConn) resp, err := client.LastBlockHeight( @@ -266,6 +283,7 @@ func (c *Client) GetLastBlockHeightByChain(chain chains.Chain) (*crosschaintypes return resp.LastBlockHeight, nil } +// GetBlockHeight returns the block height func (c *Client) GetBlockHeight() (int64, error) { client := crosschaintypes.NewQueryClient(c.grpcConn) resp, err := client.LastZetaHeight(context.Background(), &crosschaintypes.QueryLastZetaHeightRequest{}) @@ -275,6 +293,7 @@ func (c *Client) GetBlockHeight() (int64, error) { return resp.Height, nil } +// GetBaseGasPrice returns the base gas price func (c *Client) GetBaseGasPrice() (int64, error) { client := feemarkettypes.NewQueryClient(c.grpcConn) resp, err := client.Params(context.Background(), &feemarkettypes.QueryParamsRequest{}) @@ -287,6 +306,7 @@ func (c *Client) GetBaseGasPrice() (int64, error) { return resp.Params.BaseFee.Int64(), nil } +// GetBallotByID returns a ballot by ID func (c *Client) GetBallotByID(id string) (*observertypes.QueryBallotByIdentifierResponse, error) { client := observertypes.NewQueryClient(c.grpcConn) return client.BallotByIdentifier(context.Background(), &observertypes.QueryBallotByIdentifierRequest{ @@ -294,6 +314,7 @@ func (c *Client) GetBallotByID(id string) (*observertypes.QueryBallotByIdentifie }) } +// GetNonceByChain returns the nonce by chain func (c *Client) GetNonceByChain(chain chains.Chain) (observertypes.ChainNonces, error) { client := observertypes.NewQueryClient(c.grpcConn) resp, err := client.ChainNonces( @@ -306,6 +327,7 @@ func (c *Client) GetNonceByChain(chain chains.Chain) (observertypes.ChainNonces, return resp.ChainNonces, nil } +// GetAllNodeAccounts returns all node accounts func (c *Client) GetAllNodeAccounts() ([]*observertypes.NodeAccount, error) { client := observertypes.NewQueryClient(c.grpcConn) resp, err := client.NodeAccountAll(context.Background(), &observertypes.QueryAllNodeAccountRequest{}) @@ -316,6 +338,7 @@ func (c *Client) GetAllNodeAccounts() ([]*observertypes.NodeAccount, error) { return resp.NodeAccount, nil } +// GetKeyGen returns the keygen func (c *Client) GetKeyGen() (*observertypes.Keygen, error) { var err error client := observertypes.NewQueryClient(c.grpcConn) @@ -330,6 +353,7 @@ func (c *Client) GetKeyGen() (*observertypes.Keygen, error) { return nil, fmt.Errorf("failed to get keygen | err %s", err.Error()) } +// GetBallot returns a ballot by ID func (c *Client) GetBallot(ballotIdentifier string) (*observertypes.QueryBallotByIdentifierResponse, error) { client := observertypes.NewQueryClient(c.grpcConn) resp, err := client.BallotByIdentifier(context.Background(), &observertypes.QueryBallotByIdentifierRequest{ @@ -341,6 +365,7 @@ func (c *Client) GetBallot(ballotIdentifier string) (*observertypes.QueryBallotB return resp, nil } +// GetInboundTrackersForChain returns the inbound trackers for a chain func (c *Client) GetInboundTrackersForChain(chainID int64) ([]crosschaintypes.InboundTracker, error) { client := crosschaintypes.NewQueryClient(c.grpcConn) resp, err := client.InboundTrackerAllByChain( @@ -353,6 +378,7 @@ func (c *Client) GetInboundTrackersForChain(chainID int64) ([]crosschaintypes.In return resp.InboundTracker, nil } +// GetCurrentTss returns the current TSS func (c *Client) GetCurrentTss() (observertypes.TSS, error) { client := observertypes.NewQueryClient(c.grpcConn) resp, err := client.TSS(context.Background(), &observertypes.QueryGetTSSRequest{}) @@ -362,6 +388,8 @@ func (c *Client) GetCurrentTss() (observertypes.TSS, error) { return resp.TSS, nil } +// GetEthTssAddress returns the ETH TSS address +// TODO(revamp): rename to EVM func (c *Client) GetEthTssAddress() (string, error) { client := observertypes.NewQueryClient(c.grpcConn) resp, err := client.GetTssAddress(context.Background(), &observertypes.QueryGetTssAddressRequest{}) @@ -371,6 +399,7 @@ func (c *Client) GetEthTssAddress() (string, error) { return resp.Eth, nil } +// GetBtcTssAddress returns the BTC TSS address func (c *Client) GetBtcTssAddress(chainID int64) (string, error) { client := observertypes.NewQueryClient(c.grpcConn) resp, err := client.GetTssAddress(context.Background(), &observertypes.QueryGetTssAddressRequest{ @@ -382,6 +411,7 @@ func (c *Client) GetBtcTssAddress(chainID int64) (string, error) { return resp.Btc, nil } +// GetTssHistory returns the TSS history func (c *Client) GetTssHistory() ([]observertypes.TSS, error) { client := observertypes.NewQueryClient(c.grpcConn) resp, err := client.TssHistory(context.Background(), &observertypes.QueryTssHistoryRequest{}) @@ -391,6 +421,7 @@ func (c *Client) GetTssHistory() ([]observertypes.TSS, error) { return resp.TssList, nil } +// GetOutboundTracker returns the outbound tracker for a chain and nonce func (c *Client) GetOutboundTracker(chain chains.Chain, nonce uint64) (*crosschaintypes.OutboundTracker, error) { client := crosschaintypes.NewQueryClient(c.grpcConn) resp, err := client.OutboundTracker(context.Background(), &crosschaintypes.QueryGetOutboundTrackerRequest{ @@ -403,6 +434,7 @@ func (c *Client) GetOutboundTracker(chain chains.Chain, nonce uint64) (*crosscha return &resp.OutboundTracker, nil } +// GetAllOutboundTrackerByChain returns all outbound trackers for a chain func (c *Client) GetAllOutboundTrackerByChain( chainID int64, order interfaces.Order, @@ -437,6 +469,7 @@ func (c *Client) GetAllOutboundTrackerByChain( return resp.OutboundTracker, nil } +// GetPendingNoncesByChain returns the pending nonces for a chain func (c *Client) GetPendingNoncesByChain(chainID int64) (observertypes.PendingNonces, error) { client := observertypes.NewQueryClient(c.grpcConn) resp, err := client.PendingNoncesByChain( @@ -449,6 +482,7 @@ func (c *Client) GetPendingNoncesByChain(chainID int64) (observertypes.PendingNo return resp.PendingNonces, nil } +// GetBlockHeaderChainState returns the block header chain state func (c *Client) GetBlockHeaderChainState(chainID int64) (lightclienttypes.QueryGetChainStateResponse, error) { client := lightclienttypes.NewQueryClient(c.grpcConn) resp, err := client.ChainState(context.Background(), &lightclienttypes.QueryGetChainStateRequest{ChainId: chainID}) @@ -458,6 +492,7 @@ func (c *Client) GetBlockHeaderChainState(chainID int64) (lightclienttypes.Query return *resp, nil } +// GetSupportedChains returns the supported chains func (c *Client) GetSupportedChains() ([]*chains.Chain, error) { client := observertypes.NewQueryClient(c.grpcConn) resp, err := client.SupportedChains(context.Background(), &observertypes.QuerySupportedChains{}) @@ -467,6 +502,7 @@ func (c *Client) GetSupportedChains() ([]*chains.Chain, error) { return resp.GetChains(), nil } +// GetPendingNonces returns the pending nonces func (c *Client) GetPendingNonces() (*observertypes.QueryAllPendingNoncesResponse, error) { client := observertypes.NewQueryClient(c.grpcConn) resp, err := client.PendingNoncesAll(context.Background(), &observertypes.QueryAllPendingNoncesRequest{}) @@ -476,6 +512,7 @@ func (c *Client) GetPendingNonces() (*observertypes.QueryAllPendingNoncesRespons return resp, nil } +// Prove returns whether a proof is valid func (c *Client) Prove( blockHash string, txHash string, @@ -497,6 +534,7 @@ func (c *Client) Prove( return resp.Valid, nil } +// HasVoted returns whether a voter has voted func (c *Client) HasVoted(ballotIndex string, voterAddress string) (bool, error) { client := observertypes.NewQueryClient(c.grpcConn) resp, err := client.HasVoted(context.Background(), &observertypes.QueryHasVotedRequest{ @@ -509,6 +547,7 @@ func (c *Client) HasVoted(ballotIndex string, voterAddress string) (bool, error) return resp.HasVoted, nil } +// GetZetaHotKeyBalance returns the zeta hot key balance func (c *Client) GetZetaHotKeyBalance() (sdkmath.Int, error) { client := banktypes.NewQueryClient(c.grpcConn) address, err := c.keys.GetAddress() diff --git a/zetaclient/zetacore/tx.go b/zetaclient/zetacore/tx.go index b4aa0725f8..e2598eccdf 100644 --- a/zetaclient/zetacore/tx.go +++ b/zetaclient/zetacore/tx.go @@ -24,6 +24,7 @@ import ( ) // GetInBoundVoteMessage returns a new MsgVoteInbound +// TODO(revamp): move to a different file func GetInBoundVoteMessage( sender string, senderChain int64, @@ -69,6 +70,7 @@ func GasPriceMultiplier(chainID int64) (float64, error) { return 0, fmt.Errorf("cannot get gas price multiplier for unknown chain %d", chainID) } +// WrapMessageWithAuthz wraps a message with an authz message func (c *Client) WrapMessageWithAuthz(msg sdk.Msg) (sdk.Msg, clientauthz.Signer, error) { msgURL := sdk.MsgTypeURL(msg) @@ -82,6 +84,8 @@ func (c *Client) WrapMessageWithAuthz(msg sdk.Msg) (sdk.Msg, clientauthz.Signer, return &authzMessage, authzSigner, nil } +// PostGasPrice posts a gas price vote +// TODO(revamp): rename to PostVoteGasPrice func (c *Client) PostGasPrice(chain chains.Chain, gasPrice uint64, supply string, blockNum uint64) (string, error) { // apply gas price multiplier for the chain multiplier, err := GasPriceMultiplier(chain.ChainId) @@ -110,6 +114,8 @@ func (c *Client) PostGasPrice(chain chains.Chain, gasPrice uint64, supply string return "", fmt.Errorf("post gasprice failed after %d retries", DefaultRetryInterval) } +// AddOutboundTracker adds an outbound tracker +// TODO(revamp): rename to PostAddOutboundTracker func (c *Client) AddOutboundTracker( chainID int64, nonce uint64, @@ -143,6 +149,8 @@ func (c *Client) AddOutboundTracker( return zetaTxHash, nil } +// SetTSS sends message to vote tss +// TODO(revamp): rename to PostVoteTSS func (c *Client) SetTSS(tssPubkey string, keyGenZetaHeight int64, status chains.ReceiveStatus) (string, error) { signerAddress := c.keys.GetOperatorAddress().String() msg := observertypes.NewMsgVoteTSS(signerAddress, tssPubkey, keyGenZetaHeight, status) @@ -166,6 +174,8 @@ func (c *Client) SetTSS(tssPubkey string, keyGenZetaHeight int64, status chains. } // ZetacoreContextUpdater is a polling goroutine that checks and updates zetacore context at every height +// TODO(revamp): move to a different file +// TODO(revamp): rename to UpdateZetacoreContext func (c *Client) ZetacoreContextUpdater(appContext *appcontext.AppContext) { c.logger.Info().Msg("ZetacoreContextUpdater started") ticker := time.NewTicker(time.Duration(appContext.Config().ConfigUpdateTicker) * time.Second) @@ -185,6 +195,8 @@ func (c *Client) ZetacoreContextUpdater(appContext *appcontext.AppContext) { } } +// PostBlameData posts blame data message to zetacore +// TODO(revamp): rename to PostVoteBlame func (c *Client) PostBlameData(blame *blame.Blame, chainID int64, index string) (string, error) { signerAddress := c.keys.GetOperatorAddress().String() zetaBlame := observertypes.Blame{ @@ -212,6 +224,7 @@ func (c *Client) PostBlameData(blame *blame.Blame, chainID int64, index string) return "", fmt.Errorf("post blame data failed after %d retries", DefaultRetryCount) } +// PostVoteBlockHeader posts a vote on an observed block header func (c *Client) PostVoteBlockHeader( chainID int64, blockHash []byte, @@ -280,6 +293,7 @@ func (c *Client) PostVoteInbound(gasLimit, retryGasLimit uint64, msg *types.MsgV // MonitorVoteInboundResult monitors the result of a vote inbound tx // retryGasLimit is the gas limit used to resend the tx if it fails because of insufficient gas // if retryGasLimit is 0, the tx is not resent +// TODO(revamp): move to a monitor file func (c *Client) MonitorVoteInboundResult(zetaTxHash string, retryGasLimit uint64, msg *types.MsgVoteInbound) { var lastErr error @@ -330,6 +344,7 @@ func (c *Client) MonitorVoteInboundResult(zetaTxHash string, retryGasLimit uint6 } // PostVoteOutbound posts a vote on an observed outbound tx +// TODO(revamp): rename and move to a different file func (c *Client) PostVoteOutbound( cctxIndex string, outboundHash string, @@ -372,6 +387,7 @@ func (c *Client) PostVoteOutbound( } // PostVoteOutboundFromMsg posts a vote on an observed outbound tx from a MsgVoteOutbound +// TODO(revamp): rename to PostVoteOutbound func (c *Client) PostVoteOutboundFromMsg( gasLimit, retryGasLimit uint64, msg *types.MsgVoteOutbound, @@ -412,6 +428,7 @@ func (c *Client) PostVoteOutboundFromMsg( // MonitorVoteOutboundResult monitors the result of a vote outbound tx // retryGasLimit is the gas limit used to resend the tx if it fails because of insufficient gas // if retryGasLimit is 0, the tx is not resent +// TODO(revamp): move to a monitor file func (c *Client) MonitorVoteOutboundResult(zetaTxHash string, retryGasLimit uint64, msg *types.MsgVoteOutbound) { var lastErr error From a898c90098422c3a1be5d65793b5b7d92e69b4c3 Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 5 Jun 2024 15:53:36 +0200 Subject: [PATCH 08/16] add package headers --- zetaclient/authz/authz_signer.go | 1 + zetaclient/chains/bitcoin/observer/observer.go | 1 + zetaclient/chains/bitcoin/signer/signer.go | 1 + zetaclient/chains/evm/observer/observer.go | 1 + zetaclient/chains/evm/signer/signer.go | 1 + zetaclient/chains/interfaces/interfaces.go | 1 + zetaclient/compliance/compliance.go | 1 + zetaclient/config/config.go | 1 + zetaclient/context/app_context.go | 1 + zetaclient/metrics/metrics.go | 1 + zetaclient/orchestrator/orchestrator.go | 1 + zetaclient/outboundprocessor/outbound_processor_manager.go | 1 + zetaclient/ratelimiter/rate_limiter.go | 1 + zetaclient/supplychecker/zeta_supply_checker.go | 2 ++ zetaclient/tss/tss_signer.go | 1 + zetaclient/zetacore/client.go | 1 + 16 files changed, 17 insertions(+) diff --git a/zetaclient/authz/authz_signer.go b/zetaclient/authz/authz_signer.go index 378573bd17..385b0f9e7b 100644 --- a/zetaclient/authz/authz_signer.go +++ b/zetaclient/authz/authz_signer.go @@ -1,3 +1,4 @@ +// Package authz provides a signer object for transactions using grants package authz import ( diff --git a/zetaclient/chains/bitcoin/observer/observer.go b/zetaclient/chains/bitcoin/observer/observer.go index 05f63bba87..410676ed90 100644 --- a/zetaclient/chains/bitcoin/observer/observer.go +++ b/zetaclient/chains/bitcoin/observer/observer.go @@ -1,3 +1,4 @@ +// Package observer implements the Bitcoin chain observer package observer import ( diff --git a/zetaclient/chains/bitcoin/signer/signer.go b/zetaclient/chains/bitcoin/signer/signer.go index 159c4f6577..81d7f7f286 100644 --- a/zetaclient/chains/bitcoin/signer/signer.go +++ b/zetaclient/chains/bitcoin/signer/signer.go @@ -1,3 +1,4 @@ +// Package signer implements the ChainSigner interface for BTC package signer import ( diff --git a/zetaclient/chains/evm/observer/observer.go b/zetaclient/chains/evm/observer/observer.go index c61b0f78b8..e58f3b4370 100644 --- a/zetaclient/chains/evm/observer/observer.go +++ b/zetaclient/chains/evm/observer/observer.go @@ -1,3 +1,4 @@ +// Package observer implements the EVM chain observer package observer import ( diff --git a/zetaclient/chains/evm/signer/signer.go b/zetaclient/chains/evm/signer/signer.go index 32b3152cd0..dc0f39d288 100644 --- a/zetaclient/chains/evm/signer/signer.go +++ b/zetaclient/chains/evm/signer/signer.go @@ -1,3 +1,4 @@ +// Package signer implements the ChainSigner interface for EVM chains package signer import ( diff --git a/zetaclient/chains/interfaces/interfaces.go b/zetaclient/chains/interfaces/interfaces.go index 1d901d4f53..533dcc6029 100644 --- a/zetaclient/chains/interfaces/interfaces.go +++ b/zetaclient/chains/interfaces/interfaces.go @@ -1,3 +1,4 @@ +// Package interfaces provides interfaces for clients and signers for the chain to interact with package interfaces import ( diff --git a/zetaclient/compliance/compliance.go b/zetaclient/compliance/compliance.go index e085b6954b..849d56742b 100644 --- a/zetaclient/compliance/compliance.go +++ b/zetaclient/compliance/compliance.go @@ -1,3 +1,4 @@ +// Package compliance provides functions to check for compliance of cross-chain transactions package compliance import ( diff --git a/zetaclient/config/config.go b/zetaclient/config/config.go index 916f9041c1..aa0c3c7c02 100644 --- a/zetaclient/config/config.go +++ b/zetaclient/config/config.go @@ -1,3 +1,4 @@ +// Package config provides functions to load and save ZetaClient config package config import ( diff --git a/zetaclient/context/app_context.go b/zetaclient/context/app_context.go index 01ed9c565a..ffdfa05604 100644 --- a/zetaclient/context/app_context.go +++ b/zetaclient/context/app_context.go @@ -1,3 +1,4 @@ +// Package context provides global app context for ZetaClient package context import ( diff --git a/zetaclient/metrics/metrics.go b/zetaclient/metrics/metrics.go index 4c7f5ff06b..1da10d10e8 100644 --- a/zetaclient/metrics/metrics.go +++ b/zetaclient/metrics/metrics.go @@ -1,3 +1,4 @@ +// Package metrics provides metrics functionalities for the zetaclient package metrics import ( diff --git a/zetaclient/orchestrator/orchestrator.go b/zetaclient/orchestrator/orchestrator.go index dbba673641..c4ad8a37b6 100644 --- a/zetaclient/orchestrator/orchestrator.go +++ b/zetaclient/orchestrator/orchestrator.go @@ -1,3 +1,4 @@ +// Package orchestrator provides the orchestrator for orchestrating cross-chain transactions package orchestrator import ( diff --git a/zetaclient/outboundprocessor/outbound_processor_manager.go b/zetaclient/outboundprocessor/outbound_processor_manager.go index 367c2698ea..0eabd6cf8e 100644 --- a/zetaclient/outboundprocessor/outbound_processor_manager.go +++ b/zetaclient/outboundprocessor/outbound_processor_manager.go @@ -1,3 +1,4 @@ +// Package outboundprocessor provides functionalities to track outbound processing package outboundprocessor import ( diff --git a/zetaclient/ratelimiter/rate_limiter.go b/zetaclient/ratelimiter/rate_limiter.go index 0ddb3b378b..e3c69898fa 100644 --- a/zetaclient/ratelimiter/rate_limiter.go +++ b/zetaclient/ratelimiter/rate_limiter.go @@ -1,3 +1,4 @@ +// Package ratelimiter provides functionalities for rate limiting the cross-chain transactions package ratelimiter import ( diff --git a/zetaclient/supplychecker/zeta_supply_checker.go b/zetaclient/supplychecker/zeta_supply_checker.go index 94b92849ed..b9c40df5b7 100644 --- a/zetaclient/supplychecker/zeta_supply_checker.go +++ b/zetaclient/supplychecker/zeta_supply_checker.go @@ -1,3 +1,5 @@ +// Package supplychecker provides functionalities to check the total supply of Zeta tokens +// Currently not used in the codebase package supplychecker import ( diff --git a/zetaclient/tss/tss_signer.go b/zetaclient/tss/tss_signer.go index 661a3f6228..d917586833 100644 --- a/zetaclient/tss/tss_signer.go +++ b/zetaclient/tss/tss_signer.go @@ -1,3 +1,4 @@ +// Package tss provides the TSS signer functionalities for the zetaclient to sign transactions on external chains package tss import ( diff --git a/zetaclient/zetacore/client.go b/zetaclient/zetacore/client.go index f43117cd78..f1b14d06ad 100644 --- a/zetaclient/zetacore/client.go +++ b/zetaclient/zetacore/client.go @@ -1,3 +1,4 @@ +// Package zetacore provides functionalities for interacting with ZetaChain package zetacore import ( From bee7f191ac154b5325c80326e4f747b297ee401b Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 5 Jun 2024 16:05:50 +0200 Subject: [PATCH 09/16] changelog entry --- changelog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/changelog.md b/changelog.md index 6f0fa7e632..56f7cdd0ff 100644 --- a/changelog.md +++ b/changelog.md @@ -72,6 +72,10 @@ * [2191](https://github.com/zeta-chain/node/pull/2191) - Fixed conditional logic for the docker build step for non release builds to not overwrite the github tag. * [2192](https://github.com/zeta-chain/node/pull/2192) - Added release status checker and updater pipeline that will update release statuses when they go live on network. +### Documentation + +* [2321](https://github.com/zeta-chain/node/pull/2321) - improve documentation for ZetaClient functions and packages + ## v17.0.0 ### Fixes From e8ca8430eb707dda68df50cd27745b4c5d02f6f4 Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Thu, 6 Jun 2024 09:10:41 +0200 Subject: [PATCH 10/16] Update zetaclient/chains/bitcoin/observer/observer.go Co-authored-by: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> --- zetaclient/chains/bitcoin/observer/observer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zetaclient/chains/bitcoin/observer/observer.go b/zetaclient/chains/bitcoin/observer/observer.go index 410676ed90..ba6a67ff97 100644 --- a/zetaclient/chains/bitcoin/observer/observer.go +++ b/zetaclient/chains/bitcoin/observer/observer.go @@ -127,7 +127,7 @@ type Observer struct { // lastBlockScanned is the last block height scanned by the observer lastBlockScanned int64 - // pendingNonce is the number of pending nonces for outbounds + // pendingNonce is the pending nonce for outbounds pendingNonce uint64 // utxos contains the UTXOs owned by the TSS address From 66f4ce5f96c880661b7df9f6f22d917011c7ce6f Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Thu, 6 Jun 2024 09:10:50 +0200 Subject: [PATCH 11/16] Update zetaclient/chains/bitcoin/observer/observer.go Co-authored-by: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> --- zetaclient/chains/bitcoin/observer/observer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zetaclient/chains/bitcoin/observer/observer.go b/zetaclient/chains/bitcoin/observer/observer.go index ba6a67ff97..7088bc1747 100644 --- a/zetaclient/chains/bitcoin/observer/observer.go +++ b/zetaclient/chains/bitcoin/observer/observer.go @@ -520,7 +520,7 @@ func (ob *Observer) PostGasPrice() error { } // GetSenderAddressByVin get the sender address from the previous transaction -// TODO(revamp): move in upper package +// TODO(revamp): move in upper package to separate file (e.g., rpc.go) func GetSenderAddressByVin(rpcClient interfaces.BTCRPCClient, vin btcjson.Vin, net *chaincfg.Params) (string, error) { // query previous raw transaction by txid // GetTransaction requires reconfiguring the bitcoin node (txindex=1), so we use GetRawTransaction instead From da9a7f507d56fcb26c9617c91be6ed9f9ae13339 Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Thu, 6 Jun 2024 09:10:58 +0200 Subject: [PATCH 12/16] Update zetaclient/chains/bitcoin/observer/observer.go Co-authored-by: Charlie Chen <34498985+ws4charlie@users.noreply.github.com> --- zetaclient/chains/bitcoin/observer/observer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zetaclient/chains/bitcoin/observer/observer.go b/zetaclient/chains/bitcoin/observer/observer.go index 7088bc1747..e7474636a2 100644 --- a/zetaclient/chains/bitcoin/observer/observer.go +++ b/zetaclient/chains/bitcoin/observer/observer.go @@ -673,7 +673,7 @@ func (ob *Observer) SaveBroadcastedTx(txHash string, nonce uint64) { } // GetTxResultByHash gets the transaction result by hash -// TODO(revamp): move to client package +// TODO(revamp): move in upper package to separate file (e.g., rpc.go) func GetTxResultByHash( rpcClient interfaces.BTCRPCClient, txID string, From fff4353d13aa7e2afad2a3b2737f29b037ba857d Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 26 Jun 2024 16:39:36 +0200 Subject: [PATCH 13/16] apply some comments --- zetaclient/authz/authz_signer.go | 1 + .../chains/bitcoin/observer/observer.go | 1 - .../chains/bitcoin/observer/outbound.go | 4 ++-- zetaclient/chains/evm/observer/observer.go | 2 +- zetaclient/zetacore/query.go | 13 ---------- zetaclient/zetacore/query_test.go | 24 ------------------- zetaclient/zetacore/tx.go | 1 + 7 files changed, 5 insertions(+), 41 deletions(-) diff --git a/zetaclient/authz/authz_signer.go b/zetaclient/authz/authz_signer.go index 385b0f9e7b..7f9dc4d471 100644 --- a/zetaclient/authz/authz_signer.go +++ b/zetaclient/authz/authz_signer.go @@ -1,4 +1,5 @@ // Package authz provides a signer object for transactions using grants +// grants are used to allow a hotkey to sign transactions on behalf of the observers package authz import ( diff --git a/zetaclient/chains/bitcoin/observer/observer.go b/zetaclient/chains/bitcoin/observer/observer.go index e7474636a2..fe13d4ca56 100644 --- a/zetaclient/chains/bitcoin/observer/observer.go +++ b/zetaclient/chains/bitcoin/observer/observer.go @@ -53,7 +53,6 @@ const ( var _ interfaces.ChainObserver = &Observer{} // Logger contains list of loggers used by Bitcoin chain observer -// TODO(revamp): Merge this logger with the one in evm // https://github.com/zeta-chain/node/issues/2022 type Logger struct { // Chain is the parent logger for the chain diff --git a/zetaclient/chains/bitcoin/observer/outbound.go b/zetaclient/chains/bitcoin/observer/outbound.go index 24739b0692..4175eebd3a 100644 --- a/zetaclient/chains/bitcoin/observer/outbound.go +++ b/zetaclient/chains/bitcoin/observer/outbound.go @@ -332,8 +332,8 @@ func (ob *Observer) refreshPendingNonce() { } } -// getOutboundIDByNonce gets the outbound ID from the nonce of the outbound transaction. -// test is true for unit test only. +// getOutboundIDByNonce gets the outbound ID from the nonce of the outbound transaction +// test is true for unit test only func (ob *Observer) getOutboundIDByNonce(nonce uint64, test bool) (string, error) { // There are 2 types of txids an observer can trust diff --git a/zetaclient/chains/evm/observer/observer.go b/zetaclient/chains/evm/observer/observer.go index e58f3b4370..10060a0158 100644 --- a/zetaclient/chains/evm/observer/observer.go +++ b/zetaclient/chains/evm/observer/observer.go @@ -558,7 +558,7 @@ func (ob *Observer) PostGasPrice() error { } // TransactionByHash query transaction by hash via JSON-RPC -// TODO(revamp): move to a tx file +// TODO(revamp): update this method as a pure RPC method that takes two parameters (jsonRPC, and txHash) and move to upper package to file rpc.go func (ob *Observer) TransactionByHash(txHash string) (*ethrpc.Transaction, bool, error) { tx, err := ob.evmJSONRPC.EthGetTransactionByHash(txHash) if err != nil { diff --git a/zetaclient/zetacore/query.go b/zetaclient/zetacore/query.go index 3c855039c6..d57fcd9ce0 100644 --- a/zetaclient/zetacore/query.go +++ b/zetaclient/zetacore/query.go @@ -270,19 +270,6 @@ func (c *Client) GetNodeInfo() (*tmservice.GetNodeInfoResponse, error) { return nil, err } -// GetLastBlockHeightByChain returns the last block height by chain -func (c *Client) GetLastBlockHeightByChain(chain chains.Chain) (*crosschaintypes.LastBlockHeight, error) { - client := crosschaintypes.NewQueryClient(c.grpcConn) - resp, err := client.LastBlockHeight( - context.Background(), - &crosschaintypes.QueryGetLastBlockHeightRequest{Index: chain.ChainName.String()}, - ) - if err != nil { - return nil, err - } - return resp.LastBlockHeight, nil -} - // GetBlockHeight returns the block height func (c *Client) GetBlockHeight() (int64, error) { client := crosschaintypes.NewQueryClient(c.grpcConn) diff --git a/zetaclient/zetacore/query_test.go b/zetaclient/zetacore/query_test.go index 05d52fc088..70898b8e11 100644 --- a/zetaclient/zetacore/query_test.go +++ b/zetaclient/zetacore/query_test.go @@ -461,30 +461,6 @@ func TestZetacore_GetNodeInfo(t *testing.T) { require.Equal(t, expectedOutput, *resp) } -func TestZetacore_GetLastBlockHeightByChain(t *testing.T) { - index := chains.BscMainnet - expectedOutput := crosschainTypes.QueryGetLastBlockHeightResponse{ - LastBlockHeight: &crosschainTypes.LastBlockHeight{ - Index: index.ChainName.String(), - Chain: "7000", - LastOutboundHeight: 2134123, - LastInboundHeight: 1234333, - }, - } - input := crosschainTypes.QueryGetLastBlockHeightRequest{Index: index.ChainName.String()} - method := "/zetachain.zetacore.crosschain.Query/LastBlockHeight" - server := setupMockServer(t, crosschainTypes.RegisterQueryServer, method, input, expectedOutput) - server.Serve() - defer closeMockServer(t, server) - - client, err := setupZetacoreClient() - require.NoError(t, err) - - resp, err := client.GetLastBlockHeightByChain(index) - require.NoError(t, err) - require.Equal(t, expectedOutput.LastBlockHeight, resp) -} - func TestZetacore_GetZetaBlockHeight(t *testing.T) { expectedOutput := crosschainTypes.QueryLastZetaHeightResponse{Height: 12345} input := crosschainTypes.QueryLastZetaHeightRequest{} diff --git a/zetaclient/zetacore/tx.go b/zetaclient/zetacore/tx.go index e2598eccdf..7f8a535933 100644 --- a/zetaclient/zetacore/tx.go +++ b/zetaclient/zetacore/tx.go @@ -71,6 +71,7 @@ func GasPriceMultiplier(chainID int64) (float64, error) { } // WrapMessageWithAuthz wraps a message with an authz message +// used since a hotkey is used to broadcast the transactions, instead of the operator func (c *Client) WrapMessageWithAuthz(msg sdk.Msg) (sdk.Msg, clientauthz.Signer, error) { msgURL := sdk.MsgTypeURL(msg) From 3885dc7fad3e1bfed19e0bbfe03adf0678b6766d Mon Sep 17 00:00:00 2001 From: Lucas Bertrand Date: Wed, 26 Jun 2024 16:42:31 +0200 Subject: [PATCH 14/16] Apply suggestions from code review Co-authored-by: Tanmay --- zetaclient/tss/tss_signer.go | 5 +++-- zetaclient/zetacore/query.go | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/zetaclient/tss/tss_signer.go b/zetaclient/tss/tss_signer.go index d917586833..ddde72c910 100644 --- a/zetaclient/tss/tss_signer.go +++ b/zetaclient/tss/tss_signer.go @@ -477,7 +477,7 @@ func (tss *TSS) InsertPubKey(pk string) error { return nil } -// VerifyKeysharesForPubkeys verifies the keyshares for the pubkeys +// VerifyKeysharesForPubkeys verifies the keyshares present on the node. It checks whether the node has TSS key shares for the TSS ceremonies it was part of. func (tss *TSS) VerifyKeysharesForPubkeys(tssList []observertypes.TSS, granteePubKey32 string) error { for _, t := range tssList { if wasNodePartOfTss(granteePubKey32, t.TssParticipantList) { @@ -489,7 +489,7 @@ func (tss *TSS) VerifyKeysharesForPubkeys(tssList []observertypes.TSS, granteePu return nil } -// LoadTssFilesFromDirectory loads the TSS files from the directory +// LoadTssFilesFromDirectory loads the TSS files at the directory specified by the `tssPath` func (tss *TSS) LoadTssFilesFromDirectory(tssPath string) error { files, err := os.ReadDir(tssPath) if err != nil { @@ -668,6 +668,7 @@ func combineDigests(digestList []string) []byte { } // wasNodePartOfTss checks if the node was part of the TSS +// it checks whether a pubkey is part of the list used to generate the TSS , Every TSS generated on the network has its own list of associated public keys func wasNodePartOfTss(granteePubKey32 string, granteeList []string) bool { for _, grantee := range granteeList { if granteePubKey32 == grantee { diff --git a/zetaclient/zetacore/query.go b/zetaclient/zetacore/query.go index d57fcd9ce0..e90be274ff 100644 --- a/zetaclient/zetacore/query.go +++ b/zetaclient/zetacore/query.go @@ -68,7 +68,7 @@ func (c *Client) GetChainParamsForChainID(externalChainID int64) (*observertypes return resp.ChainParams, nil } -// GetChainParams returns the chain params +// GetChainParams returns all the chain params func (c *Client) GetChainParams() ([]*observertypes.ChainParams, error) { client := observertypes.NewQueryClient(c.grpcConn) var err error @@ -270,7 +270,7 @@ func (c *Client) GetNodeInfo() (*tmservice.GetNodeInfoResponse, error) { return nil, err } -// GetBlockHeight returns the block height +// GetBlockHeight returns the zetachain block height func (c *Client) GetBlockHeight() (int64, error) { client := crosschaintypes.NewQueryClient(c.grpcConn) resp, err := client.LastZetaHeight(context.Background(), &crosschaintypes.QueryLastZetaHeightRequest{}) @@ -456,7 +456,7 @@ func (c *Client) GetAllOutboundTrackerByChain( return resp.OutboundTracker, nil } -// GetPendingNoncesByChain returns the pending nonces for a chain +// GetPendingNoncesByChain returns the pending nonces for a chain and current tss address func (c *Client) GetPendingNoncesByChain(chainID int64) (observertypes.PendingNonces, error) { client := observertypes.NewQueryClient(c.grpcConn) resp, err := client.PendingNoncesByChain( @@ -521,7 +521,7 @@ func (c *Client) Prove( return resp.Valid, nil } -// HasVoted returns whether a voter has voted +// HasVoted returns whether an observer has voted func (c *Client) HasVoted(ballotIndex string, voterAddress string) (bool, error) { client := observertypes.NewQueryClient(c.grpcConn) resp, err := client.HasVoted(context.Background(), &observertypes.QueryHasVotedRequest{ From ce1d37224c1a35c91d2c0c315c211a527da63437 Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 26 Jun 2024 16:42:43 +0200 Subject: [PATCH 15/16] add one comment --- zetaclient/tss/tss_signer.go | 1 + 1 file changed, 1 insertion(+) diff --git a/zetaclient/tss/tss_signer.go b/zetaclient/tss/tss_signer.go index ddde72c910..da7f4018ee 100644 --- a/zetaclient/tss/tss_signer.go +++ b/zetaclient/tss/tss_signer.go @@ -574,6 +574,7 @@ func GetTssAddrEVM(tssPubkey string) (ethcommon.Address, error) { } // TestKeysign tests the keysign +// it is called when a new TSS is generated to ensure the network works as expected // TODO(revamp): move to a test package func TestKeysign(tssPubkey string, tssServer *tss.TssServer) error { log.Info().Msg("trying keysign...") From 675b98a3b122c8a769bddc2d1b3ec3cd3300a02e Mon Sep 17 00:00:00 2001 From: lumtis Date: Wed, 26 Jun 2024 17:16:10 +0200 Subject: [PATCH 16/16] add some fixes --- zetaclient/chains/interfaces/interfaces.go | 1 - zetaclient/testutils/mocks/zetacore_client.go | 7 ------- zetaclient/tss/tss_signer.go | 2 +- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/zetaclient/chains/interfaces/interfaces.go b/zetaclient/chains/interfaces/interfaces.go index dff546709c..2272ef1dfe 100644 --- a/zetaclient/chains/interfaces/interfaces.go +++ b/zetaclient/chains/interfaces/interfaces.go @@ -97,7 +97,6 @@ type ZetacoreClient interface { GetKeys() keyinterfaces.ObserverKeys GetKeyGen() (*observertypes.Keygen, error) GetBlockHeight() (int64, error) - GetLastBlockHeightByChain(chain chains.Chain) (*crosschaintypes.LastBlockHeight, error) ListPendingCctx(chainID int64) ([]*crosschaintypes.CrossChainTx, uint64, error) ListPendingCctxWithinRatelimit() ([]*crosschaintypes.CrossChainTx, uint64, int64, string, bool, error) GetRateLimiterInput(window int64) (crosschaintypes.QueryRateLimiterInputResponse, error) diff --git a/zetaclient/testutils/mocks/zetacore_client.go b/zetaclient/testutils/mocks/zetacore_client.go index 953d8ce287..2f413a8764 100644 --- a/zetaclient/testutils/mocks/zetacore_client.go +++ b/zetaclient/testutils/mocks/zetacore_client.go @@ -145,13 +145,6 @@ func (m *MockZetacoreClient) GetBlockHeight() (int64, error) { return 0, nil } -func (m *MockZetacoreClient) GetLastBlockHeightByChain(_ chains.Chain) (*crosschaintypes.LastBlockHeight, error) { - if m.paused { - return nil, errors.New(ErrMsgPaused) - } - return &crosschaintypes.LastBlockHeight{}, nil -} - func (m *MockZetacoreClient) GetRateLimiterInput(_ int64) (crosschaintypes.QueryRateLimiterInputResponse, error) { if m.paused { return crosschaintypes.QueryRateLimiterInputResponse{}, errors.New(ErrMsgPaused) diff --git a/zetaclient/tss/tss_signer.go b/zetaclient/tss/tss_signer.go index 1a5ca63620..08d48833db 100644 --- a/zetaclient/tss/tss_signer.go +++ b/zetaclient/tss/tss_signer.go @@ -669,7 +669,7 @@ func combineDigests(digestList []string) []byte { } // wasNodePartOfTss checks if the node was part of the TSS -// it checks whether a pubkey is part of the list used to generate the TSS , Every TSS generated on the network has its own list of associated public keys +// it checks whether a pubkey is part of the list used to generate the TSS , Every TSS generated on the network has its own list of associated public keys func wasNodePartOfTss(granteePubKey32 string, granteeList []string) bool { for _, grantee := range granteeList { if granteePubKey32 == grantee {