Skip to content

Commit

Permalink
1. add the entire process of automatical sending and checking for bat…
Browse files Browse the repository at this point in the history
…ch test transactions.

2. add the command-line for the test tool
  • Loading branch information
TimmyExogenous committed Nov 21, 2024
1 parent 243ede4 commit c9e6035
Show file tree
Hide file tree
Showing 8 changed files with 443 additions and 58 deletions.
98 changes: 98 additions & 0 deletions cmd/test-tool/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package main

import (
"context"
"fmt"
"os"
"os/signal"
"syscall"

"github.com/ExocoreNetwork/exocore/testutil/batch"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

var configPath string

// Root command
var rootCmd = &cobra.Command{
Use: "app",
Short: "test tool application with external configuration",
Long: `This is a test tool application that loads configuration from an external file.`,
PersistentPreRunE: func(_ *cobra.Command, _ []string) error {
// Initialize the manager before executing any command
var err error
config, err := loadConfig(configPath)
if err != nil {
return fmt.Errorf("failed to load config: %v", err)
}
// Initialize the manager with the provided configuration file
appManager, err = batch.NewManager(context.Background(), config)
if err != nil {
return fmt.Errorf("failed to initialize manager: %v", err)
}
return nil
},
}

// Global appManager variable to access the manager in subcommands
var appManager *batch.Manager

// start command
var startCmd = &cobra.Command{
Use: "start",
Short: "start the test tool",
Args: cobra.NoArgs,
Run: func(_ *cobra.Command, _ []string) {
// Start the app manager in a separate goroutine
go func() {
if err := appManager.Start(); err != nil {
fmt.Printf("Error starting the test tool: %v\n", err)
}
}()

Check notice

Code scanning / CodeQL

Spawning a Go routine Note test

Spawning a Go routine may be a possible source of non-determinism

// Set up channel to listen for OS interrupt signals (like Ctrl+C)
stopChan := make(chan os.Signal, 1)
signal.Notify(stopChan, syscall.SIGINT, syscall.SIGTERM)

// Wait for an interrupt signal
<-stopChan
// Shutdown appManager gracefully
fmt.Println("Shutting down...")
close(appManager.Shutdown)
appManager.Close()
},
}

// loadConfig loads the configuration file and parses it into the Config struct
func loadConfig(configPath string) (*batch.EndToEndConfig, error) {
// Set the config file path and type (can be "yaml", "json", etc.)
viper.SetConfigFile(configPath)

// Read the configuration file
if err := viper.ReadInConfig(); err != nil {
return nil, fmt.Errorf("error reading config file, %s", err)
}

// Unmarshal the config into a Config struct
var cfg batch.EndToEndConfig
if err := viper.Unmarshal(&cfg); err != nil {
return nil, fmt.Errorf("unable to decode into struct, %v", err)
}

return &cfg, nil
}

func main() {
// Add persistent flag for the configuration file
rootCmd.PersistentFlags().StringVar(&configPath, "config", "test-tool-config.toml", "Path to the configuration file")

// Add subcommands
rootCmd.AddCommand(startCmd)

// Execute the root command
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
31 changes: 19 additions & 12 deletions testutil/batch/batch_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ func (m *Manager) enqueueTxAndSaveRecord(params *EnqueueTxParams) error {
// send the tx info to the queue
sk, err := crypto.ToECDSA(params.staker.Sk)
if err != nil {
return xerrors.Errorf("can't convert the sk to ecdsa private key,staker:%v,err:%s", params.staker.ID, err)
return xerrors.Errorf("can't convert the Sk to ecdsa private key,staker:%v,err:%s", params.staker.ID, err)
}

evmTxInQueue := &EvmTxInQueue{
sk: sk,
Sk: sk,
From: params.staker.EvmAddress(),
UseExternalNonce: true,
Nonce: *params.nonce,
Expand All @@ -68,21 +68,29 @@ func (m *Manager) enqueueTxAndSaveRecord(params *EnqueueTxParams) error {
Data: params.msgData,
TxRecordID: txRecord.ID,
}
m.TxsQueue <- evmTxInQueue
select {
case m.TxsQueue <- evmTxInQueue:
// Successfully sent to the channel
case <-m.Shutdown:
// Received a shutdown signal, return immediately
fmt.Println("Received shutdown signal, stopping...")
return nil
}
// increase the nonce
*params.nonce++
return nil
}

func (m *Manager) EnqueueDepositWithdrawLSTTxs(isWithdrawal bool) error {
func (m *Manager) EnqueueDepositWithdrawLSTTxs(msgType string) error {
if msgType != assets.MethodDepositLST && msgType != assets.MethodWithdrawLST {
return xerrors.Errorf("EnqueueDepositWithdrawLSTTxs invalid msg type:%s", msgType)
}
assetsAbi, err := abi.JSON(strings.NewReader(assets.AssetsABI))
if err != nil {
return err
}
opAmount := DefaultDepositAmount
msgType := assets.MethodDepositLST
if isWithdrawal {
msgType = assets.MethodWithdrawLST
if msgType == assets.MethodWithdrawLST {
// The remaining amount has been delegated to the operators.
// Therefore, we use half of the total deposit amount as the withdrawal amount.
opAmount = HalfDefaultDepositAmount
Expand Down Expand Up @@ -129,7 +137,10 @@ func (m *Manager) EnqueueDepositWithdrawLSTTxs(isWithdrawal bool) error {
return nil
}

func (m *Manager) EnqueueDelegationTxs(isUndelegation bool) error {
func (m *Manager) EnqueueDelegationTxs(msgType string) error {
if msgType != delegation.MethodDelegate && msgType != delegation.MethodUndelegate {
return xerrors.Errorf("EnqueueDelegationTxs invalid msg type:%s", msgType)
}
delegationAbi, err := abi.JSON(strings.NewReader(delegation.DelegationABI))
if err != nil {
return err
Expand All @@ -138,10 +149,6 @@ func (m *Manager) EnqueueDelegationTxs(isUndelegation bool) error {
if err != nil {
return err
}
msgType := delegation.MethodDelegate
if isUndelegation {
msgType = delegation.MethodUndelegate
}

ethHTTPClient := m.NodeEVMHTTPClients[DefaultNodeIndex]
// construct and push all messages into the queue
Expand Down
Loading

0 comments on commit c9e6035

Please sign in to comment.