Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

docs(zetaclient): add more function and package documentation #2321

Merged
merged 18 commits into from
Jun 26, 2024
Merged
4 changes: 4 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@
* [2335](https://github.com/zeta-chain/node/pull/2335) - ci: updated the artillery report to publish to artillery cloud
* [2377](https://github.com/zeta-chain/node/pull/2377) - ci: adjusted sast-linters.yml to not scan itself, nor alert on removal of nosec.

### Documentation

* [2321](https://github.com/zeta-chain/node/pull/2321) - improve documentation for ZetaClient functions and packages

## v17.0.0

### Fixes
Expand Down
8 changes: 8 additions & 0 deletions zetaclient/authz/authz_signer.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Package authz provides a signer object for transactions using grants
lumtis marked this conversation as resolved.
Show resolved Hide resolved
// grants are used to allow a hotkey to sign transactions on behalf of the observers
package authz

import (
Expand All @@ -7,18 +9,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
lumtis marked this conversation as resolved.
Show resolved Hide resolved
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
lumtis marked this conversation as resolved.
Show resolved Hide resolved
lumtis marked this conversation as resolved.
Show resolved Hide resolved
func init() {
signersList := make(map[string]Signer)
for _, tx := range crosschaintypes.GetAllAuthzZetaclientTxTypes() {
Expand All @@ -27,6 +33,7 @@ func init() {
signers = signersList
}

// SetupAuthZSignerList sets the granter and grantee for all the signers
lumtis marked this conversation as resolved.
Show resolved Hide resolved
lumtis marked this conversation as resolved.
Show resolved Hide resolved
func SetupAuthZSignerList(granter string, grantee sdk.AccAddress) {
for k, v := range signers {
v.GranterAddress = granter
Expand All @@ -35,6 +42,7 @@ func SetupAuthZSignerList(granter string, grantee sdk.AccAddress) {
}
}

// GetSigner returns the signer for a given msgURL
lumtis marked this conversation as resolved.
Show resolved Hide resolved
func GetSigner(msgURL string) Signer {
return signers[msgURL]
}
2 changes: 2 additions & 0 deletions zetaclient/authz/authz_signer_test.go
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
package authz_test

// NOTE: test file currently created empty to add the package in the test coverage scope
9 changes: 9 additions & 0 deletions zetaclient/chains/bitcoin/observer/inbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import (
)

// WatchInbound watches Bitcoin chain for inbounds on a ticker
// It starts a ticker and run ObserveInbound
// TODO(revamp): move all ticker related methods in the same file
lumtis marked this conversation as resolved.
Show resolved Hide resolved
func (ob *Observer) WatchInbound() {
ticker, err := types.NewDynamicTicker("Bitcoin_WatchInbound", ob.GetChainParams().InboundTicker)
if err != nil {
Expand All @@ -37,6 +39,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():
Expand All @@ -58,6 +61,7 @@ func (ob *Observer) WatchInbound() {
}

// ObserveInbound observes the 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.btcClient.GetBlockCount()
Expand Down Expand Up @@ -171,6 +175,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 {
Expand Down Expand Up @@ -200,6 +205,7 @@ func (ob *Observer) WatchInboundTracker() {
}

// ProcessInboundTrackers processes inbound trackers
// TODO(revamp): move inbound tracker logic in a specific file
lumtis marked this conversation as resolved.
Show resolved Hide resolved
lumtis marked this conversation as resolved.
Show resolved Hide resolved
lumtis marked this conversation as resolved.
Show resolved Hide resolved
func (ob *Observer) ProcessInboundTrackers() error {
trackers, err := ob.ZetacoreClient().GetInboundTrackersForChain(ob.Chain().ChainId)
if err != nil {
Expand Down Expand Up @@ -328,6 +334,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)
Expand Down Expand Up @@ -360,6 +367,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
lumtis marked this conversation as resolved.
Show resolved Hide resolved
lumtis marked this conversation as resolved.
Show resolved Hide resolved
func (ob *Observer) DoesInboundContainsRestrictedAddress(inTx *BTCInboundEvent) bool {
receiver := ""
parsedAddress, _, err := chains.ParseAddressAndData(hex.EncodeToString(inTx.MemoBytes))
Expand All @@ -376,6 +384,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
lumtis marked this conversation as resolved.
Show resolved Hide resolved
lumtis marked this conversation as resolved.
Show resolved Hide resolved
func GetBtcEvent(
rpcClient interfaces.BTCRPCClient,
tx btcjson.TxRawResult,
Expand Down
16 changes: 14 additions & 2 deletions zetaclient/chains/bitcoin/observer/observer.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package observer implements the Bitcoin chain observer
package observer

import (
Expand Down Expand Up @@ -54,6 +55,7 @@ type Logger struct {
}

// BTCInboundEvent represents an incoming transaction event
// TODO(revamp): Move to inbound
lumtis marked this conversation as resolved.
Show resolved Hide resolved
type BTCInboundEvent struct {
// FromAddress is the first input address
FromAddress string
Expand All @@ -69,7 +71,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
Expand Down Expand Up @@ -190,7 +192,7 @@ func (ob *Observer) GetChainParams() observertypes.ChainParams {
return ob.ChainParams()
}

// 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("observer is starting for chain %d", ob.Chain().ChainId)

Expand All @@ -214,6 +216,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)
Expand Down Expand Up @@ -297,6 +301,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()
Expand Down Expand Up @@ -333,6 +339,7 @@ func (ob *Observer) WatchGasPrice() {
}

// PostGasPrice posts gas price to zetacore
// TODO(revamp): move to gas price file
func (ob *Observer) PostGasPrice() error {
// hardcode gas price here since this RPC is not available on regtest
if chains.IsBitcoinRegnet(ob.Chain().ChainId) {
Expand Down Expand Up @@ -379,6 +386,7 @@ func (ob *Observer) PostGasPrice() error {
}

// GetSenderAddressByVin get the sender address from the previous transaction
// 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
Expand Down Expand Up @@ -421,6 +429,7 @@ func GetSenderAddressByVin(rpcClient interfaces.BTCRPCClient, vin btcjson.Vin, n
}

// WatchUTXOs watches bitcoin chain for UTXOs owned by the TSS address
// 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 {
Expand Down Expand Up @@ -448,6 +457,7 @@ func (ob *Observer) WatchUTXOs() {
}

// FetchUTXOs fetches TSS-owned UTXOs from the Bitcoin node
// TODO(revamp): move to UTXO file
func (ob *Observer) FetchUTXOs() error {
defer func() {
if err := recover(); err != nil {
Expand Down Expand Up @@ -511,6 +521,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()
Expand Down Expand Up @@ -641,6 +652,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
Expand Down
8 changes: 8 additions & 0 deletions zetaclient/chains/bitcoin/observer/outbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,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
ws4charlie marked this conversation as resolved.
Show resolved Hide resolved
lumtis marked this conversation as resolved.
Show resolved Hide resolved
lumtis marked this conversation as resolved.
Show resolved Hide resolved
func (ob *Observer) WatchOutbound() {
ticker, err := types.NewDynamicTicker("Bitcoin_WatchOutbound", ob.GetChainParams().OutboundTicker)
if err != nil {
Expand Down Expand Up @@ -111,6 +113,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
lumtis marked this conversation as resolved.
Show resolved Hide resolved
lumtis marked this conversation as resolved.
Show resolved Hide resolved
func (ob *Observer) IsOutboundProcessed(cctx *crosschaintypes.CrossChainTx, logger zerolog.Logger) (bool, bool, error) {
params := *cctx.GetCurrentOutboundParam()
sendHash := cctx.Index
Expand Down Expand Up @@ -213,6 +216,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
lumtis marked this conversation as resolved.
Show resolved Hide resolved
lumtis marked this conversation as resolved.
Show resolved Hide resolved
func (ob *Observer) SelectUTXOs(
amount float64,
utxosToSpend uint16,
Expand Down Expand Up @@ -329,6 +334,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
// 1. The ones had been verified and saved by observer self.
Expand Down Expand Up @@ -363,6 +370,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)
Expand Down
5 changes: 5 additions & 0 deletions zetaclient/chains/bitcoin/signer/signer.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package signer implements the ChainSigner interface for BTC
package signer

import (
Expand Down Expand Up @@ -168,6 +169,7 @@ func (signer *Signer) AddWithdrawTxOutputs(
}

// SignWithdrawTx receives utxos sorted by value, amount in BTC, feeRate in BTC per Kb
// TODO(revamp): simplify the function
lumtis marked this conversation as resolved.
Show resolved Hide resolved
func (signer *Signer) SignWithdrawTx(
to btcutil.Address,
amount float64,
Expand Down Expand Up @@ -291,6 +293,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())

Expand All @@ -311,6 +314,8 @@ func (signer *Signer) Broadcast(signedTx *wire.MsgTx) error {
return nil
}

// TryProcessOutbound signs and broadcasts a BTC transaction from a new outbound
lumtis marked this conversation as resolved.
Show resolved Hide resolved
// TODO(revamp): simplify the function
func (signer *Signer) TryProcessOutbound(
cctx *types.CrossChainTx,
outboundProcessor *outboundprocessor.Processor,
Expand Down
5 changes: 5 additions & 0 deletions zetaclient/chains/bitcoin/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import (
"github.com/pkg/errors"
)

// TODO(revamp): Remove utils.go and move the functions to the appropriate files
lumtis marked this conversation as resolved.
Show resolved Hide resolved

// PrettyPrintStruct returns a pretty-printed string representation of a struct
func PrettyPrintStruct(val interface{}) (string, error) {
prettyStruct, err := json.MarshalIndent(
val,
Expand All @@ -20,6 +23,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.
Expand All @@ -39,6 +43,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
Expand Down
4 changes: 4 additions & 0 deletions zetaclient/chains/evm/observer/inbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
lumtis marked this conversation as resolved.
Show resolved Hide resolved
lumtis marked this conversation as resolved.
Show resolved Hide resolved
func (ob *Observer) WatchInbound() {
ticker, err := clienttypes.NewDynamicTicker(
fmt.Sprintf("EVM_WatchInbound_%d", ob.Chain().ChainId),
Expand Down Expand Up @@ -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
lumtis marked this conversation as resolved.
Show resolved Hide resolved
lumtis marked this conversation as resolved.
Show resolved Hide resolved
func (ob *Observer) WatchInboundTracker() {
ticker, err := clienttypes.NewDynamicTicker(
fmt.Sprintf("EVM_WatchInboundTracker_%d", ob.Chain().ChainId),
Expand Down Expand Up @@ -101,6 +103,7 @@ func (ob *Observer) WatchInboundTracker() {
}

// ProcessInboundTrackers processes inbound trackers from zetacore
// TODO(revamp): move inbound tracker function to a separate file
lumtis marked this conversation as resolved.
Show resolved Hide resolved
func (ob *Observer) ProcessInboundTrackers() error {
trackers, err := ob.ZetacoreClient().GetInboundTrackersForChain(ob.Chain().ChainId)
if err != nil {
Expand Down Expand Up @@ -152,6 +155,7 @@ func (ob *Observer) ProcessInboundTrackers() error {
return nil
}

// ObserveInbound observes the evm chain for inbounds and posts votes to zetacore
lumtis marked this conversation as resolved.
Show resolved Hide resolved
lumtis marked this conversation as resolved.
Show resolved Hide resolved
func (ob *Observer) ObserveInbound(sampledLogger zerolog.Logger) error {
// get and update latest block height
blockNumber, err := ob.evmClient.BlockNumber(context.Background())
Expand Down
Loading
Loading