Skip to content

Commit

Permalink
docs(zetaclient): add more function and package documentation (#2321)
Browse files Browse the repository at this point in the history
* bitcoin

* add revamp todos

* evm

* config

* keys and metrics

* orchestrator and tss

* zetacore package

* add package headers

* changelog entry

* Update zetaclient/chains/bitcoin/observer/observer.go

Co-authored-by: Charlie Chen <[email protected]>

* Update zetaclient/chains/bitcoin/observer/observer.go

Co-authored-by: Charlie Chen <[email protected]>

* Update zetaclient/chains/bitcoin/observer/observer.go

Co-authored-by: Charlie Chen <[email protected]>

* apply some comments

* Apply suggestions from code review

Co-authored-by: Tanmay <[email protected]>

* add one comment

* add some fixes

---------

Co-authored-by: Charlie Chen <[email protected]>
Co-authored-by: Tanmay <[email protected]>
  • Loading branch information
3 people authored Jun 26, 2024
1 parent f2ac8f6 commit 57457fd
Show file tree
Hide file tree
Showing 41 changed files with 306 additions and 52 deletions.
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
// 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
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() {
Expand All @@ -27,6 +33,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
Expand All @@ -35,6 +42,7 @@ func SetupAuthZSignerList(granter string, grantee sdk.AccAddress) {
}
}

// GetSigner returns the signer for a given msgURL
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
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
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
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
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
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
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
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
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
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
// 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

// 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
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
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
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
func (ob *Observer) ObserveInbound(sampledLogger zerolog.Logger) error {
// get and update latest block height
blockNumber, err := ob.evmClient.BlockNumber(context.Background())
Expand Down
Loading

0 comments on commit 57457fd

Please sign in to comment.