From f148821c03664b2eb25bddec36e6593da32c500b Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Sun, 27 Oct 2024 23:02:35 +0700 Subject: [PATCH] update tests --- broadcast/broadcast.go | 2 +- lib/lib.go | 2 +- main.go | 129 ++--------------------------------------- main_test.go | 99 ++++++++++++++++++++++++++----- 4 files changed, 92 insertions(+), 140 deletions(-) diff --git a/broadcast/broadcast.go b/broadcast/broadcast.go index aa6b19d..592be92 100644 --- a/broadcast/broadcast.go +++ b/broadcast/broadcast.go @@ -50,7 +50,7 @@ func Transaction(txBytes []byte, rpcEndpoint string) (*coretypes.ResultBroadcast } // broadcastLoop handles the main transaction broadcasting logic -func BroadcastLoop( +func Loop( txParams types.TransactionParams, batchSize int, ) (successfulTxns, failedTxns int, responseCodes map[uint32]int, updatedSequence uint64) { diff --git a/lib/lib.go b/lib/lib.go index 55ec797..41c4c67 100644 --- a/lib/lib.go +++ b/lib/lib.go @@ -34,7 +34,7 @@ var httpClient = &http.Client{ }, } -func GetAccountInfo(address string, config types.Config) (seqint uint64, accnum uint64, err error) { +func GetAccountInfo(address string, config types.Config) (seqint, accnum uint64, err error) { resp, err := HTTPGet(config.Nodes.API + "/cosmos/auth/v1beta1/accounts/" + address) if err != nil { return 0, 0, fmt.Errorf("failed to get initial sequence: %v", err) diff --git a/main.go b/main.go index bdf3f5b..b9ae4cf 100644 --- a/main.go +++ b/main.go @@ -6,8 +6,6 @@ import ( "fmt" "log" "os" - "strconv" - "strings" "sync" "time" @@ -128,10 +126,10 @@ func main() { msgParams := config.MsgParams // Initialize gRPC client - grpcClient, err := client.NewGRPCClient(config.Nodes.GRPC) - if err != nil { - log.Fatalf("Failed to create gRPC client: %v", err) - } + // grpcClient, err := client.NewGRPCClient(config.Nodes.GRPC) + // if err != nil { + // log.Fatalf("Failed to create gRPC client: %v", err) + // } var wg sync.WaitGroup for _, account := range accounts { @@ -160,7 +158,7 @@ func main() { } // Broadcast transactions - successfulTxns, failedTxns, responseCodes, _ := broadcastLoop(txParams, BatchSize, grpcClient) + successfulTxns, failedTxns, responseCodes, _ := broadcast.Loop(txParams, BatchSize) fmt.Printf("Account %s: Successful transactions: %d, Failed transactions: %d\n", acct.Address, successfulTxns, failedTxns) fmt.Println("Response code breakdown:") @@ -174,123 +172,6 @@ func main() { wg.Wait() } -// broadcastLoop handles the main transaction broadcasting logic -func broadcastLoop( - txParams types.TransactionParams, - batchSize int, - grpcClient *client.GRPCClient, -) (successfulTxns, failedTxns int, responseCodes map[uint32]int, updatedSequence uint64) { - successfulTxns = 0 - failedTxns = 0 - responseCodes = make(map[uint32]int) - sequence := txParams.Sequence - - for i := 0; i < batchSize; i++ { - currentSequence := sequence - - fmt.Println("FROM LOOP, currentSequence", currentSequence) - fmt.Println("FROM LOOP, accNum", txParams.AccNum) - fmt.Println("FROM LOOP, chainID", txParams.ChainID) - - ctx := context.Background() - start := time.Now() - grpcResp, _, err := broadcast.SendTransactionViaGRPC( - ctx, - txParams, - sequence, - grpcClient, - ) - elapsed := time.Since(start) - - fmt.Println("FROM MAIN, err", err) - fmt.Println("FROM MAIN, resp", grpcResp.Code) - - if err == nil { - fmt.Printf("%s Transaction succeeded, sequence: %d, time: %v\n", - time.Now().Format("15:04:05.000"), currentSequence, elapsed) - successfulTxns++ - responseCodes[grpcResp.Code]++ - sequence++ // Increment sequence for next transaction - continue - } - - fmt.Printf("%s Error: %v\n", time.Now().Format("15:04:05.000"), err) - fmt.Println("FROM MAIN, resp.Code", grpcResp.Code) - - if grpcResp.Code == 32 { - // Extract the expected sequence number from the error message - expectedSeq, parseErr := extractExpectedSequence(err.Error()) - if parseErr != nil { - fmt.Printf("%s Failed to parse expected sequence: %v\n", time.Now().Format("15:04:05.000"), parseErr) - failedTxns++ - continue - } - - sequence = expectedSeq - fmt.Printf("%s Set sequence to expected value %d due to mismatch\n", - time.Now().Format("15:04:05"), sequence) - - // Re-send the transaction with the correct sequence - start = time.Now() - grpcResp, respBytes, err := broadcast.SendTransactionViaGRPC( - ctx, - txParams, - sequence, - grpcClient, - ) - - fmt.Println("FROM MAIN, grpcResp", grpcResp) - fmt.Println("FROM MAIN, respBytes", respBytes) - - elapsed = time.Since(start) - - if err != nil { - fmt.Printf("%s Error after adjusting sequence: %v\n", time.Now().Format("15:04:05.000"), err) - failedTxns++ - continue - } - - fmt.Printf("%s Transaction succeeded after adjusting sequence, sequence: %d, time: %v\n", - time.Now().Format("15:04:05"), sequence, elapsed) - successfulTxns++ - responseCodes[grpcResp.Code]++ - sequence++ // Increment sequence for next transaction - continue - } - failedTxns++ - - } - updatedSequence = sequence - return successfulTxns, failedTxns, responseCodes, updatedSequence -} - -// Function to extract the expected sequence number from the error message -func extractExpectedSequence(errMsg string) (uint64, error) { - // Parse the error message to extract the expected sequence number - // Example error message: - // "account sequence mismatch, expected 42, got 41: incorrect account sequence" - index := strings.Index(errMsg, "expected ") - if index == -1 { - return 0, errors.New("expected sequence not found in error message") - } - - start := index + len("expected ") - rest := errMsg[start:] - parts := strings.SplitN(rest, ",", 2) - if len(parts) < 1 { - return 0, errors.New("failed to split expected sequence from error message") - } - - expectedSeqStr := strings.TrimSpace(parts[0]) - expectedSeq, err := strconv.ParseUint(expectedSeqStr, 10, 64) - if err != nil { - return 0, fmt.Errorf("failed to parse expected sequence number: %v", err) - } - - return expectedSeq, nil -} - -// adjustBalances transfers funds between accounts to balance their balances within the threshold // adjustBalances transfers funds between accounts to balance their balances within the threshold func adjustBalances(accounts []types.Account, balances map[string]sdkmath.Int, config types.Config) error { if len(accounts) == 0 { diff --git a/main_test.go b/main_test.go index e62902d..d7d1918 100644 --- a/main_test.go +++ b/main_test.go @@ -5,18 +5,21 @@ import ( "fmt" "net/http" "net/http/httptest" + "os" "strings" "testing" - sdkmath "cosmossdk.io/math" - "github.com/cosmos/cosmos-sdk/crypto/hd" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/go-bip39" "github.com/cosmos/ibc-go/modules/apps/callbacks/testing/simapp/params" "github.com/somatic-labs/meteorite/broadcast" "github.com/somatic-labs/meteorite/lib" "github.com/somatic-labs/meteorite/types" + + sdkmath "cosmossdk.io/math" + + "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" ) func TestExtractExpectedSequence(t *testing.T) { @@ -141,6 +144,74 @@ func TestTransferFunds(t *testing.T) { } } +func TestAdjustBalancesWithSeedPhrase(t *testing.T) { + // Create a temporary seed phrase file + mnemonic := []byte("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about") + tmpfile, err := os.CreateTemp("", "seedphrase") + if err != nil { + t.Fatalf("Failed to create temp file: %v", err) + } + defer os.Remove(tmpfile.Name()) + + if _, err := tmpfile.Write(mnemonic); err != nil { + t.Fatalf("Failed to write to temp file: %v", err) + } + if err := tmpfile.Close(); err != nil { + t.Fatalf("Failed to close temp file: %v", err) + } + + // Set up test config + config := types.Config{ + Chain: "test-chain", + Prefix: "cosmos", + Denom: "uatom", + Slip44: 118, + Nodes: types.NodesConfig{ + RPC: []string{"http://localhost:26657"}, + API: "http://localhost:1317", + }, + } + + // Create test accounts from seed phrase + var accounts []types.Account + for i := 0; i < 3; i++ { // Create 3 test accounts + position := uint32(i) + privKey, pubKey, acctAddress := lib.GetPrivKey(config, mnemonic, position) + accounts = append(accounts, types.Account{ + PrivKey: privKey, + PubKey: pubKey, + Address: acctAddress, + Position: position, + }) + } + + // Set up mock balances where only the 0th position is funded + balances := map[string]sdkmath.Int{ + accounts[0].Address: sdkmath.NewInt(1000000), + accounts[1].Address: sdkmath.ZeroInt(), + accounts[2].Address: sdkmath.ZeroInt(), + } + + // Create a test server to mock the API responses + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Mock successful transaction response + fmt.Fprintln(w, `{"height":"1","txhash":"hash","code":0}`) + })) + defer ts.Close() + config.Nodes.API = ts.URL + config.Nodes.RPC = []string{ts.URL} + + // Run adjustBalances + err = adjustBalances(accounts, balances, config) + if err != nil { + t.Errorf("adjustBalances() error = %v", err) + } + + // Verify that balances were attempted to be adjusted + // Note: In a real scenario, you'd want to verify the actual balance changes, + // but since we're using a mock server, we're just verifying the function ran without error +} + func TestAdjustBalances(t *testing.T) { tests := []struct { name string @@ -161,12 +232,12 @@ func TestAdjustBalances(t *testing.T) { { name: "zero total balance", accounts: []types.Account{ - {Address: "mantra1test1"}, - {Address: "mantra1test2"}, + {Address: "cosmos1test1"}, + {Address: "cosmos1test2"}, }, balances: map[string]sdkmath.Int{ - "mantra1test1": sdkmath.ZeroInt(), - "mantra1test2": sdkmath.ZeroInt(), + "cosmos1test1": sdkmath.ZeroInt(), + "cosmos1test2": sdkmath.ZeroInt(), }, config: types.Config{ Denom: "uom", @@ -176,12 +247,12 @@ func TestAdjustBalances(t *testing.T) { { name: "uneven balances need adjustment", accounts: []types.Account{ - {Address: "mantra1test1"}, - {Address: "mantra1test2"}, + {Address: "cosmos1test1"}, + {Address: "cosmos1test2"}, }, balances: map[string]sdkmath.Int{ - "mantra1test1": sdkmath.NewInt(1000000), - "mantra1test2": sdkmath.NewInt(0), + "cosmos1test1": sdkmath.NewInt(1000000), + "cosmos1test2": sdkmath.NewInt(0), }, config: types.Config{ Denom: "uom", @@ -268,7 +339,7 @@ func TestGetAccountInfo(t *testing.T) { }{ { name: "valid response", - address: "mantra1test1", + address: "cosmos1test1", mockResp: `{ "account": { "sequence": "42", @@ -281,7 +352,7 @@ func TestGetAccountInfo(t *testing.T) { }, { name: "invalid sequence", - address: "mantra1test2", + address: "cosmos1test2", mockResp: `{ "account": { "sequence": "invalid",