diff --git a/cmd/soroban-rpc/internal/test/cli_test.go b/cmd/soroban-rpc/internal/test/cli_test.go index c84ddc50f4..3dc6780a64 100644 --- a/cmd/soroban-rpc/internal/test/cli_test.go +++ b/cmd/soroban-rpc/internal/test/cli_test.go @@ -54,7 +54,7 @@ func outputsContractIDInLastLine(t *testing.T, output string) { func TestCLIContractDeploy(t *testing.T) { NewCLITest(t) - output := runSuccessfulCLICmd(t, "contract deploy --salt 0 --wasm "+helloWorldContractPath) + output := deploy(t, helloWorldContractPath, 0) outputsContractIDInLastLine(t, output) } @@ -68,51 +68,25 @@ func TestCLIContractDeployAndInvoke(t *testing.T) { func TestCLISimulateTransactionBumpAndRestoreFootprint(t *testing.T) { test := NewCLITest(t) - ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) - client := jrpc2.NewClient(ch, nil) - - sourceAccount := keypair.Root(StandaloneNetworkPassphrase) - address := sourceAccount.Address() - account := txnbuild.NewSimpleAccount(address, 0) - - helloWorldContract := getHelloWorldContract(t) - - params := preflightTransactionParams(t, client, txnbuild.TransactionParams{ - SourceAccount: &account, - IncrementSequenceNum: true, - Operations: []txnbuild.Operation{ - createInstallContractCodeOperation(account.AccountID, helloWorldContract), - }, - BaseFee: txnbuild.MinBaseFee, - Preconditions: txnbuild.Preconditions{ - TimeBounds: txnbuild.NewInfiniteTimeout(), - }, - }) - tx, err := txnbuild.NewTransaction(params) - assert.NoError(t, err) - sendSuccessfulTransaction(t, client, sourceAccount, tx) - - params = preflightTransactionParams(t, client, txnbuild.TransactionParams{ - SourceAccount: &account, - IncrementSequenceNum: true, - Operations: []txnbuild.Operation{ - createCreateContractOperation(t, address, helloWorldContract, StandaloneNetworkPassphrase), - }, - BaseFee: txnbuild.MinBaseFee, - Preconditions: txnbuild.Preconditions{ - TimeBounds: txnbuild.NewInfiniteTimeout(), - }, - }) - tx, err = txnbuild.NewTransaction(params) - assert.NoError(t, err) - sendSuccessfulTransaction(t, client, sourceAccount, tx) + contractID := deploy(t, helloWorldContractPath, 0) + count := invoke(t, contractID, 0, "inc") + require.Equal(t, "1", count) + waitForKey(t, test, testContractID(t, 0), symToScVal(xdr.ScSymbol("COUNTER"))) + count = runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", contractID)) + require.Equal(t, "2", count) +} - contractID := getContractID(t, address, testSalt, StandaloneNetworkPassphrase) - runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", contractID)) +func symToScVal(s xdr.ScSymbol) xdr.ScVal { + res, _ := xdr.NewScVal(xdr.ScValTypeScvSymbol, s) + return res +} +func waitForKey(t *testing.T, test *Test, contractID [32]byte, scValKey xdr.ScVal) { + ch := jhttp.NewChannel(test.sorobanRPCURL(), nil) + client := jrpc2.NewClient(ch, nil) // get the counter ledger entry expiration + contractIDHash := xdr.Hash(contractID) - counterSym := xdr.ScSymbol("COUNTER") key := xdr.LedgerKey{ Type: xdr.LedgerEntryTypeContractData, ContractData: &xdr.LedgerKeyContractData{ @@ -120,10 +94,7 @@ func TestCLISimulateTransactionBumpAndRestoreFootprint(t *testing.T) { Type: xdr.ScAddressTypeScAddressTypeContract, ContractId: &contractIDHash, }, - Key: xdr.ScVal{ - Type: xdr.ScValTypeScvSymbol, - Sym: &counterSym, - }, + Key: scValKey, Durability: xdr.ContractDataDurabilityPersistent, }, } @@ -150,42 +121,6 @@ func TestCLISimulateTransactionBumpAndRestoreFootprint(t *testing.T) { assert.NoError(t, xdr.SafeUnmarshalBase64(getLedgerEntryResult.XDR, &entry)) assert.Equal(t, xdr.LedgerEntryTypeExpiration, entry.Type) - initialExpirationSeq := entry.Expiration.ExpirationLedgerSeq - - // bump the initial expiration - params = preflightTransactionParams(t, client, txnbuild.TransactionParams{ - SourceAccount: &account, - IncrementSequenceNum: true, - Operations: []txnbuild.Operation{ - &txnbuild.BumpFootprintExpiration{ - LedgersToExpire: 20, - Ext: xdr.TransactionExt{ - V: 1, - SorobanData: &xdr.SorobanTransactionData{ - Resources: xdr.SorobanResources{ - Footprint: xdr.LedgerFootprint{ - ReadOnly: []xdr.LedgerKey{key}, - }, - }, - }, - }, - }, - }, - BaseFee: txnbuild.MinBaseFee, - Preconditions: txnbuild.Preconditions{ - TimeBounds: txnbuild.NewInfiniteTimeout(), - }, - }) - tx, err = txnbuild.NewTransaction(params) - assert.NoError(t, err) - sendSuccessfulTransaction(t, client, sourceAccount, tx) - - err = client.CallResult(context.Background(), "getLedgerEntry", getLedgerEntryrequest, &getLedgerEntryResult) - assert.NoError(t, err) - assert.NoError(t, xdr.SafeUnmarshalBase64(getLedgerEntryResult.XDR, &entry)) - assert.Equal(t, xdr.LedgerEntryTypeExpiration, entry.Type) - newExpirationSeq := entry.Expiration.ExpirationLedgerSeq - assert.Greater(t, newExpirationSeq, initialExpirationSeq) // Wait until it expires waitForExpiration := func() { @@ -208,8 +143,21 @@ func TestCLISimulateTransactionBumpAndRestoreFootprint(t *testing.T) { require.True(t, expired) } waitForExpiration() - output := runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --id %s -- inc", contractID)) - require.Equal(t, "2", output) +} + +func deploy(t *testing.T, wasmPath string, id uint32) string { + testSaltHex := "a1" + output := runSuccessfulCLICmd(t, fmt.Sprintf("contract deploy --hd-path %d --salt %s --wasm %s", id, testSaltHex, wasmPath)) + contractID := strings.TrimSpace(output) + return contractID +} + +// func bump(t *testing.T, contractID string, keyBase64 string) string { +// return runSuccessfulCLICmd(t, fmt.Sprintf("contract bump --id=%s, --key-xdr=%s", contractID, keyBase64)) +// } + +func invoke(t *testing.T, contractID string, testAccountID uint32, args string) string { + return runSuccessfulCLICmd(t, fmt.Sprintf("contract invoke --hd-path %d --id %s -- %s", testAccountID, contractID, args)) } func runSuccessfulCLICmd(t *testing.T, cmd string) string { @@ -218,7 +166,7 @@ func runSuccessfulCLICmd(t *testing.T, cmd string) string { return res.Stdout() } -func runCLICommand(t *testing.T, cmd string) *icmd.Result { +func cliCmd(t *testing.T, cmd string) icmd.Cmd { args := []string{"run", "-q", "--", "--vv"} parsedArgs, err := shlex.Split(cmd) require.NoError(t, err, cmd) @@ -228,7 +176,19 @@ func runCLICommand(t *testing.T, cmd string) *icmd.Result { fmt.Sprintf("SOROBAN_RPC_URL=http://localhost:%d/", sorobanRPCPort), fmt.Sprintf("SOROBAN_NETWORK_PASSPHRASE=%s", StandaloneNetworkPassphrase), ) - return icmd.RunCmd(c) + return c +} + +func runCLICommand(t *testing.T, cmd string) *icmd.Result { + return icmd.RunCmd(cliCmd(t, cmd)) +} + +func testAccount(t *testing.T, id uint32) string { + return strings.Trim(runSuccessfulCLICmd(t, fmt.Sprintf("config identity address --hd-path %d", id)), "\n") +} + +func testContractID(t *testing.T, id uint32) [32]byte { + return getContractID(t, testAccount(t, id), testSalt, StandaloneNetworkPassphrase) } const MILLION string = "1000000"