diff --git a/.gitignore b/.gitignore index e647197ef8..2c7607e11c 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,6 @@ build/linux # Go workspace files go.work go.work.sum + +debug.log +run-test.sh \ No newline at end of file diff --git a/go.mod b/go.mod index ab1fdb0acd..10f0f876d0 100644 --- a/go.mod +++ b/go.mod @@ -231,7 +231,8 @@ replace ( github.com/cometbft/cometbft => github.com/kava-labs/cometbft v0.37.9-kava.1 github.com/cometbft/cometbft-db => github.com/kava-labs/cometbft-db v0.9.1-kava.2 // Use cosmos-sdk fork with backported fix for unsafe-reset-all, staking transfer events, and custom tally handler support - github.com/cosmos/cosmos-sdk => github.com/kava-labs/cosmos-sdk v0.47.10-iavl-v1-kava.1 + // github.com/cosmos/cosmos-sdk => github.com/kava-labs/cosmos-sdk v0.47.10-iavl-v1-kava.1 + github.com/cosmos/cosmos-sdk => /Users/yevheniishcherbina/go/src/github.com/Kava-Labs/cosmos-sdk // See https://github.com/cosmos/cosmos-sdk/pull/13093 github.com/dgrijalva/jwt-go => github.com/golang-jwt/jwt/v4 v4.4.2 // Tracking kava-labs/go-ethereum kava/release/v1.10 branch diff --git a/go.sum b/go.sum index 7934ead58c..87357fc0c5 100644 --- a/go.sum +++ b/go.sum @@ -892,8 +892,6 @@ github.com/kava-labs/cometbft v0.37.9-kava.1 h1:0mMsAhpV8p0peD9sabIZ//M4nP6LiiZ0 github.com/kava-labs/cometbft v0.37.9-kava.1/go.mod h1:j0Q3RqrCd+cztWCugs3obbzC4NyHGBPZZjtm/fWV00I= github.com/kava-labs/cometbft-db v0.9.1-kava.2 h1:ZQaio886ifvml9XtJB4IYHhlArgA3+/a5Zwidg7H2J8= github.com/kava-labs/cometbft-db v0.9.1-kava.2/go.mod h1:PvUZbx7zeR7I4CAvtKBoii/5ia5gXskKjDjIVpt7gDw= -github.com/kava-labs/cosmos-sdk v0.47.10-iavl-v1-kava.1 h1:vQwrm3sdAG1pkwrsi2mmCHSGDje5fzUR6vApEux/nVA= -github.com/kava-labs/cosmos-sdk v0.47.10-iavl-v1-kava.1/go.mod h1:OwLYEBcsnijCLE8gYkwQ7jycZZ/Acd+a83pJU+V+MKw= github.com/kava-labs/ethermint v0.21.1-0.20240802224012-586960857184 h1:MWwCXFnkagXk93QiiD41I+S9wyrHZUQWLRFKo2tXL6A= github.com/kava-labs/ethermint v0.21.1-0.20240802224012-586960857184/go.mod h1:kbyr3La2Co3Hy3U3N2EvVk7W1srQ2x88JUpgsu2KrXo= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 63e63c467b..c855dbb2e0 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -112,6 +112,41 @@ func (suite *IntegrationTestSuite) TestTransferOverEVM() { suite.Equal(sdkmath.NewInt(9e5).Sub(ukavaUsedForGas), balance.AmountOf("ukava")) } +// example test that signs & broadcasts an EVM tx +func (suite *IntegrationTestSuite) TestTransferOverEVM_TODO() { + // fund an account that can perform the transfer + initialFunds := ukava(1e6) // 1 KAVA + acc := suite.Kava.NewFundedAccount("evm-test-transfer", sdk.NewCoins(initialFunds)) + + // get a rando account to send kava to + randomAddr := app.RandomAddress() + to := util.SdkToEvmAddress(randomAddr) + + // example fetching of nonce (account sequence) + nonce, err := suite.Kava.EvmClient.PendingNonceAt(context.Background(), acc.EvmAddress) + suite.NoError(err) + suite.Equal(uint64(0), nonce) // sanity check. the account should have no prior txs + + // transfer kava over EVM + kavaToTransfer := big.NewInt(1e17) // .1 KAVA; akava has 18 decimals. + req := util.EvmTxRequest{ + Tx: ethtypes.NewTransaction(nonce, to, kavaToTransfer, 1e5, minEvmGasPrice, nil), + Data: "any ol' data to track this through the system", + } + res := acc.SignAndBroadcastEvmTx(req) + suite.Require().NoError(res.Err) + suite.Equal(ethtypes.ReceiptStatusSuccessful, res.Receipt.Status) + + // evm txs refund unused gas. so to know the expected balance we need to know how much gas was used. + ukavaUsedForGas := sdkmath.NewIntFromBigInt(minEvmGasPrice). + Mul(sdkmath.NewIntFromUint64(res.Receipt.GasUsed)). + QuoRaw(1e12) // convert akava to ukava + + // expect (9 - gas used) KAVA remaining in account. + balance := suite.Kava.QuerySdkForBalances(acc.SdkAddress) + suite.Equal(sdkmath.NewInt(9e5).Sub(ukavaUsedForGas), balance.AmountOf("ukava")) +} + // TestIbcTransfer transfers KAVA from the primary kava chain (suite.Kava) to the ibc chain (suite.Ibc). // Note that because the IBC chain also runs kava's binary, this tests both the sending & receiving. func (suite *IntegrationTestSuite) TestIbcTransfer() { @@ -174,3 +209,68 @@ func (suite *IntegrationTestSuite) TestIbcTransfer() { return found }, 15*time.Second, 1*time.Second) } + +// TestIbcTransfer transfers KAVA from the primary kava chain (suite.Kava) to the ibc chain (suite.Ibc). +// Note that because the IBC chain also runs kava's binary, this tests both the sending & receiving. +func (suite *IntegrationTestSuite) TestIbcTransfer_TODO() { + //suite.SkipIfIbcDisabled() + + //banktypes.NewMsgSend() + + // ARRANGE + // setup kava account + funds := ukava(1e5) // .1 KAVA + kavaAcc := suite.Kava.NewFundedAccount("ibc-transfer-kava-side", sdk.NewCoins(funds)) + // setup ibc account + ibcAcc := suite.Ibc.NewFundedAccount("ibc-transfer-ibc-side", sdk.NewCoins()) + + gasLimit := int64(2e5) + fee := ukava(200) + + fundsToSend := ukava(5e4) // .005 KAVA + transferMsg := ibctypes.NewMsgTransfer( + testutil.IbcPort, + testutil.IbcChannel, + fundsToSend, + kavaAcc.SdkAddress.String(), + ibcAcc.SdkAddress.String(), + ibcclienttypes.NewHeight(0, 0), // timeout height disabled when 0 + uint64(time.Now().Add(30*time.Second).UnixNano()), + "", + ) + // initial - sent - fee + expectedSrcBalance := funds.Sub(fundsToSend).Sub(fee) + + // ACT + // IBC transfer from kava -> ibc + transferTo := util.KavaMsgRequest{ + Msgs: []sdk.Msg{transferMsg}, + GasLimit: uint64(gasLimit), + FeeAmount: sdk.NewCoins(fee), + Memo: "sent from Kava!", + } + res := kavaAcc.SignAndBroadcastKavaTx(transferTo) + + // ASSERT + suite.NoError(res.Err) + + // the balance should be deducted from kava account + suite.Eventually(func() bool { + balance := suite.Kava.QuerySdkForBalances(kavaAcc.SdkAddress) + return balance.AmountOf("ukava").Equal(expectedSrcBalance.Amount) + }, 10*time.Second, 1*time.Second) + + // expect the balance to be transferred to the ibc chain! + suite.Eventually(func() bool { + balance := suite.Ibc.QuerySdkForBalances(ibcAcc.SdkAddress) + found := false + for _, c := range balance { + // find the ibc denom coin + if strings.HasPrefix(c.Denom, "ibc/") { + suite.Equal(fundsToSend.Amount, c.Amount) + found = true + } + } + return found + }, 15*time.Second, 1*time.Second) +} diff --git a/tests/e2e/kvtool b/tests/e2e/kvtool index 20d8e0dcff..7a258021c1 160000 --- a/tests/e2e/kvtool +++ b/tests/e2e/kvtool @@ -1 +1 @@ -Subproject commit 20d8e0dcff557a456041e7bfea48bf3c6207ef8a +Subproject commit 7a258021c15c671f5146626738c4bbf607b66731 diff --git a/tests/e2e/testutil/account.go b/tests/e2e/testutil/account.go index eebca6300a..941c335d92 100644 --- a/tests/e2e/testutil/account.go +++ b/tests/e2e/testutil/account.go @@ -3,6 +3,7 @@ package testutil import ( "context" "encoding/hex" + "encoding/json" "fmt" "log" "math/big" @@ -236,10 +237,18 @@ func (chain *Chain) NewFundedAccount(name string, funds sdk.Coins) *SigningAccou bal.IsAllGT(funds), "funded account lacks funds for account %s\nneeds: %s\nhas: %s", name, funds, bal, ) + fmt.Printf("balance before: %v\n", bal.AmountOf("ukava")) whale.l.Printf("attempting to fund created account (%s=%s)\n", name, acc.SdkAddress.String()) res := whale.BankSend(acc.SdkAddress, funds) + resInJSON, err := json.Marshal(res) + require.NoError(chain.t, err) + fmt.Printf("resInJSON: %s\n", resInJSON) + + bal = chain.QuerySdkForBalances(whale.SdkAddress) + fmt.Printf("balance after: %v\n", bal.AmountOf("ukava")) + require.NoErrorf(chain.t, res.Err, "failed to fund new account %s: %s", name, res.Err) whale.l.Printf("successfully funded [%s]\n", name) diff --git a/tests/util/sdksigner.go b/tests/util/sdksigner.go index 9fdc59efe2..0151293ac3 100644 --- a/tests/util/sdksigner.go +++ b/tests/util/sdksigner.go @@ -287,6 +287,8 @@ func (s *KavaSigner) Run(requests <-chan KavaMsgRequest) (<-chan KavaMsgResponse } broadcastResponse, err := s.txClient.BroadcastTx(context.Background(), &broadcastRequest) + fmt.Printf("BroadcastTx TxHash: %v\n", broadcastResponse.TxResponse.TxHash) + // set to determine action at the end of loop // default is OK txResult := txOK @@ -387,6 +389,8 @@ func Sign( txBuilder sdkclient.TxBuilder, signerData authsigning.SignerData, ) (authsigning.Tx, []byte, error) { + fmt.Printf("SIGN was called!\n") + signatureData := signing.SingleSignatureData{ SignMode: signing.SignMode_SIGN_MODE_DIRECT, Signature: nil, @@ -417,6 +421,11 @@ func Sign( return txBuilder.GetTx(), nil, err } + //txBuilder.SetTimeoutHeight(12) + + timeoutHeight := txBuilder.GetTx().GetTimeoutHeight() + fmt.Printf("timeoutHeight: %v\n", timeoutHeight) + txBytes, err := txConfig.TxEncoder()(txBuilder.GetTx()) if err != nil { return txBuilder.GetTx(), nil, err