|
8 | 8 | "encoding/json"
|
9 | 9 | "fmt"
|
10 | 10 | "os"
|
| 11 | + "strings" |
11 | 12 | "testing"
|
12 | 13 |
|
13 | 14 | "github.com/stretchr/testify/require"
|
@@ -1086,3 +1087,112 @@ func readTestAminoTxBinary(t *testing.T, aminoCodec *codec.LegacyAmino) ([]byte,
|
1086 | 1087 | require.NoError(t, err)
|
1087 | 1088 | return txJSONBytes, &stdTx
|
1088 | 1089 | }
|
| 1090 | + |
| 1091 | +func TestSimulateTx_GasImprovements(t *testing.T) { |
| 1092 | + systest.Sut.ResetChain(t) |
| 1093 | + |
| 1094 | + cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose) |
| 1095 | + // get validator address |
| 1096 | + valAddr := cli.GetKeyAddr("node0") |
| 1097 | + // use node 1 as granter |
| 1098 | + granter := cli.GetKeyAddr("node1") |
| 1099 | + |
| 1100 | + require.NotEmpty(t, valAddr) |
| 1101 | + |
| 1102 | + // add new key |
| 1103 | + receiverAddr := cli.AddKey("account1") |
| 1104 | + |
| 1105 | + systest.Sut.StartChain(t) |
| 1106 | + |
| 1107 | + baseURL := systest.Sut.APIAddress() |
| 1108 | + |
| 1109 | + // node1 grant to node0 |
| 1110 | + grantCmdArgs := []string{"tx", "feegrant", "grant", granter, valAddr, "--chain-id=" + cli.ChainID()} |
| 1111 | + rsp := cli.Run(grantCmdArgs...) |
| 1112 | + txResult, found := cli.AwaitTxCommitted(rsp) |
| 1113 | + require.True(t, found) |
| 1114 | + systest.RequireTxSuccess(t, txResult) |
| 1115 | + |
| 1116 | + sendSimulateCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--chain-id=" + cli.ChainID(), "--sign-mode=direct", "--generate-only"} |
| 1117 | + bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--chain-id=" + cli.ChainID()} |
| 1118 | + testCases := []struct { |
| 1119 | + name string |
| 1120 | + simulateArgs []string |
| 1121 | + txArgs []string |
| 1122 | + }{ |
| 1123 | + { |
| 1124 | + "simulate without fees", |
| 1125 | + sendSimulateCmdArgs, |
| 1126 | + bankSendCmdArgs, |
| 1127 | + }, |
| 1128 | + { |
| 1129 | + "simulate with fees", |
| 1130 | + append(sendSimulateCmdArgs, "--fees=1stake"), |
| 1131 | + bankSendCmdArgs, |
| 1132 | + }, |
| 1133 | + { |
| 1134 | + "simulate without fee-granter", |
| 1135 | + sendSimulateCmdArgs, |
| 1136 | + append(bankSendCmdArgs, fmt.Sprintf("--fee-granter=%s", granter)), |
| 1137 | + }, |
| 1138 | + { |
| 1139 | + "simulate with fee-granter", |
| 1140 | + append(sendSimulateCmdArgs, fmt.Sprintf("--fee-granter=%s", granter)), |
| 1141 | + append(bankSendCmdArgs, fmt.Sprintf("--fee-granter=%s", granter)), |
| 1142 | + }, |
| 1143 | + } |
| 1144 | + |
| 1145 | + for _, tc := range testCases { |
| 1146 | + t.Run(tc.name, func(t *testing.T) { |
| 1147 | + txlen := 1 |
| 1148 | + gasSimulated := make([]int64, txlen) |
| 1149 | + gasAdjustment := make([]float64, txlen) |
| 1150 | + |
| 1151 | + for i := 0; i < txlen; i++ { |
| 1152 | + // create unsign tx |
| 1153 | + res := cli.RunCommandWithArgs(tc.simulateArgs...) |
| 1154 | + txFile := systest.StoreTempFile(t, []byte(res)) |
| 1155 | + |
| 1156 | + res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), "--from="+valAddr, "--chain-id="+cli.ChainID(), "--keyring-backend=test", "--home="+systest.Sut.NodeDir(0)) |
| 1157 | + signedTxFile := systest.StoreTempFile(t, []byte(res)) |
| 1158 | + |
| 1159 | + res = cli.RunCommandWithArgs("tx", "encode", signedTxFile.Name()) |
| 1160 | + txBz, err := base64.StdEncoding.DecodeString(res) |
| 1161 | + require.NoError(t, err) |
| 1162 | + |
| 1163 | + reqBz, err := json.Marshal(&tx.SimulateRequest{TxBytes: txBz}) |
| 1164 | + require.NoError(t, err) |
| 1165 | + |
| 1166 | + resBz, err := testutil.PostRequest(fmt.Sprintf("%s/cosmos/tx/v1beta1/simulate", baseURL), "application/json", reqBz) |
| 1167 | + require.NoError(t, err) |
| 1168 | + gasUsed := gjson.Get(string(resBz), "gas_info.gas_used").Int() |
| 1169 | + require.True(t, gasUsed > 0) |
| 1170 | + gasSimulated[i] = gasUsed |
| 1171 | + } |
| 1172 | + |
| 1173 | + for i := 0; i < txlen; i++ { |
| 1174 | + // Submit tx with gas return from simulate |
| 1175 | + gasAdjustment[i] = 0.99 |
| 1176 | + // test valid transaction |
| 1177 | + shouldRerun := true |
| 1178 | + for shouldRerun { |
| 1179 | + gasAdjustment[i] = gasAdjustment[i] + 0.01 |
| 1180 | + gasUse := int64(gasAdjustment[i] * float64(gasSimulated[i])) |
| 1181 | + rsp := cli.Run(append(tc.txArgs, fmt.Sprintf("--gas=%d", gasUse))...) |
| 1182 | + // rerun if tx err and increase gas-adjustment by 1% |
| 1183 | + shouldRerun = strings.Contains(gjson.Get(rsp, "raw_log").String(), "out of gas") || gjson.Get(rsp, "gas_used").Int() == int64(0) || gjson.Get(rsp, "code").Int() != 0 |
| 1184 | + fmt.Println("gasAdjustment", i, gasAdjustment[i]) |
| 1185 | + } |
| 1186 | + } |
| 1187 | + |
| 1188 | + // Calculate average adjustments |
| 1189 | + total := 0.0 |
| 1190 | + for i := 0; i < txlen; i++ { |
| 1191 | + total = total + gasAdjustment[i] |
| 1192 | + } |
| 1193 | + average := total / float64(txlen) |
| 1194 | + result := fmt.Sprintf("Test case %s average gas adjustment is: %f", tc.name, average) |
| 1195 | + fmt.Println(result) |
| 1196 | + }) |
| 1197 | + } |
| 1198 | +} |
0 commit comments