forked from cerc-io/laconicd-deprecated
rpc: debug_traceTransaction fails for succesful tx (#720)
* Problem: traceTransaction fails for succesful tx Solution: - Change the context to the begining of the block, rather than the end of it, while override block context to correct one pass predecessors pass current block information to grpc query * changelog * fix build * fix lint * refactor traceBlock * update protobuf * fix Predecessors * traceBlock refactor * refactor traceBlock response * Update proto/ethermint/evm/v1/tx.proto Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Update proto/ethermint/evm/v1/query.proto Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Update proto/ethermint/evm/v1/query.proto Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Update proto/ethermint/evm/v1/query.proto Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Update proto/ethermint/evm/v1/query.proto Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Update proto/ethermint/evm/v1/query.proto Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * check tx index is not out of bound * fix build * Update rpc/ethereum/namespaces/debug/api.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Update rpc/ethereum/namespaces/debug/api.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Update rpc/ethereum/namespaces/debug/api.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * Update rpc/ethereum/namespaces/debug/api.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * remove prealloc * add traceBlock test * Update x/evm/keeper/grpc_query.go Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * use bytes2Hex * fix error message * add comment * Apply suggestions from code review Co-authored-by: Freddy Caceres <freddy.caceres@crypto.com> Co-authored-by: crypto-facs <84574577+crypto-facs@users.noreply.github.com> Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
co-authored by
Federico Kunze Küllmer
Freddy Caceres
crypto-facs
parent
7c7f3f02bb
commit
2a205e561a
@@ -360,16 +360,34 @@ func (k Keeper) TraceTx(c context.Context, req *types.QueryTraceTxRequest) (*typ
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
ctx = ctx.WithBlockHeight(req.BlockNumber)
|
||||
ctx = ctx.WithBlockTime(req.BlockTime)
|
||||
ctx = ctx.WithHeaderHash(common.Hex2Bytes(req.BlockHash))
|
||||
k.WithContext(ctx)
|
||||
|
||||
params := k.GetParams(ctx)
|
||||
ethCfg := params.ChainConfig.EthereumConfig(k.eip155ChainID)
|
||||
signer := ethtypes.MakeSigner(ethCfg, big.NewInt(ctx.BlockHeight()))
|
||||
tx := req.Msg.AsTransaction()
|
||||
baseFee := k.feeMarketKeeper.GetBaseFee(ctx)
|
||||
|
||||
result, err := k.traceTx(ctx, signer, req.TxIndex, ethCfg, tx, baseFee, req.TraceConfig)
|
||||
for i, tx := range req.Predecessors {
|
||||
ethTx := tx.AsTransaction()
|
||||
msg, err := ethTx.AsMessage(signer, baseFee)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
k.SetTxHashTransient(ethTx.Hash())
|
||||
k.SetTxIndexTransient(uint64(i))
|
||||
|
||||
if _, err := k.ApplyMessage(msg, types.NewNoOpTracer(), true); err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
tx := req.Msg.AsTransaction()
|
||||
result, err := k.traceTx(ctx, signer, req.TxIndex, ethCfg, tx, baseFee, req.TraceConfig, false)
|
||||
if err != nil {
|
||||
// error will be returned with detail status from traceTx
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -383,6 +401,54 @@ func (k Keeper) TraceTx(c context.Context, req *types.QueryTraceTxRequest) (*typ
|
||||
}, nil
|
||||
}
|
||||
|
||||
// TraceBlock configures a new tracer according to the provided configuration, and
|
||||
// executes the given message in the provided environment for all the transactions in the queried block.
|
||||
// The return value will be tracer dependent.
|
||||
func (k Keeper) TraceBlock(c context.Context, req *types.QueryTraceBlockRequest) (*types.QueryTraceBlockResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
|
||||
if req.TraceConfig != nil && req.TraceConfig.Limit < 0 {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "output limit cannot be negative, got %d", req.TraceConfig.Limit)
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
ctx = ctx.WithBlockHeight(req.BlockNumber)
|
||||
ctx = ctx.WithBlockTime(req.BlockTime)
|
||||
ctx = ctx.WithHeaderHash(common.Hex2Bytes(req.BlockHash))
|
||||
k.WithContext(ctx)
|
||||
|
||||
params := k.GetParams(ctx)
|
||||
ethCfg := params.ChainConfig.EthereumConfig(k.eip155ChainID)
|
||||
signer := ethtypes.MakeSigner(ethCfg, big.NewInt(ctx.BlockHeight()))
|
||||
baseFee := k.feeMarketKeeper.GetBaseFee(ctx)
|
||||
|
||||
txsLength := len(req.Txs)
|
||||
results := make([]*types.TxTraceResult, 0, txsLength)
|
||||
|
||||
for i, tx := range req.Txs {
|
||||
result := types.TxTraceResult{}
|
||||
ethTx := tx.AsTransaction()
|
||||
traceResult, err := k.traceTx(ctx, signer, uint64(i), ethCfg, ethTx, baseFee, req.TraceConfig, true)
|
||||
if err != nil {
|
||||
result.Error = err.Error()
|
||||
continue
|
||||
}
|
||||
result.Result = traceResult
|
||||
results = append(results, &result)
|
||||
}
|
||||
|
||||
resultData, err := json.Marshal(results)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return &types.QueryTraceBlockResponse{
|
||||
Data: resultData,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (k *Keeper) traceTx(
|
||||
ctx sdk.Context,
|
||||
signer ethtypes.Signer,
|
||||
@@ -391,6 +457,7 @@ func (k *Keeper) traceTx(
|
||||
tx *ethtypes.Transaction,
|
||||
baseFee *big.Int,
|
||||
traceConfig *types.TraceConfig,
|
||||
commitMessage bool,
|
||||
) (*interface{}, error) {
|
||||
// Assemble the structured logger or the JavaScript tracer
|
||||
var (
|
||||
@@ -462,7 +529,7 @@ func (k *Keeper) traceTx(
|
||||
k.SetTxHashTransient(txHash)
|
||||
k.SetTxIndexTransient(txIndex)
|
||||
|
||||
res, err := k.ApplyMessage(msg, tracer, false)
|
||||
res, err := k.ApplyMessage(msg, tracer, commitMessage)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
@@ -596,8 +596,10 @@ func (suite *KeeperTestSuite) TestTraceTx() {
|
||||
ctx := sdk.WrapSDKContext(suite.ctx)
|
||||
// TODO deploy contract that triggers internal transactions
|
||||
var (
|
||||
txMsg *types.MsgEthereumTx
|
||||
traceConfig *types.TraceConfig
|
||||
txMsg *types.MsgEthereumTx
|
||||
traceConfig *types.TraceConfig
|
||||
txIndex uint64
|
||||
predecessors []*types.MsgEthereumTx
|
||||
)
|
||||
|
||||
testCases := []struct {
|
||||
@@ -610,16 +612,20 @@ func (suite *KeeperTestSuite) TestTraceTx() {
|
||||
{
|
||||
msg: "default trace",
|
||||
malleate: func() {
|
||||
txIndex = 0
|
||||
traceConfig = nil
|
||||
predecessors = []*types.MsgEthereumTx{}
|
||||
},
|
||||
expPass: true,
|
||||
traceResponse: []byte{0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d},
|
||||
}, {
|
||||
msg: "javascript tracer",
|
||||
malleate: func() {
|
||||
txIndex = 0
|
||||
traceConfig = &types.TraceConfig{
|
||||
Tracer: "{data: [], fault: function(log) {}, step: function(log) { if(log.op.toString() == \"CALL\") this.data.push(log.stack.peek(0)); }, result: function() { return this.data; }}",
|
||||
}
|
||||
predecessors = []*types.MsgEthereumTx{}
|
||||
},
|
||||
expPass: true,
|
||||
traceResponse: []byte{0x5b, 0x5d},
|
||||
@@ -627,7 +633,9 @@ func (suite *KeeperTestSuite) TestTraceTx() {
|
||||
{
|
||||
msg: "default trace with dynamicTxFee",
|
||||
malleate: func() {
|
||||
txIndex = 0
|
||||
traceConfig = nil
|
||||
predecessors = []*types.MsgEthereumTx{}
|
||||
},
|
||||
expPass: true,
|
||||
traceResponse: []byte{0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d},
|
||||
@@ -635,14 +643,35 @@ func (suite *KeeperTestSuite) TestTraceTx() {
|
||||
}, {
|
||||
msg: "javascript tracer with dynamicTxFee",
|
||||
malleate: func() {
|
||||
txIndex = 0
|
||||
traceConfig = &types.TraceConfig{
|
||||
Tracer: "{data: [], fault: function(log) {}, step: function(log) { if(log.op.toString() == \"CALL\") this.data.push(log.stack.peek(0)); }, result: function() { return this.data; }}",
|
||||
}
|
||||
predecessors = []*types.MsgEthereumTx{}
|
||||
},
|
||||
expPass: true,
|
||||
traceResponse: []byte{0x5b, 0x5d},
|
||||
dynamicTxFee: true,
|
||||
},
|
||||
{
|
||||
msg: "default tracer with predecessors",
|
||||
malleate: func() {
|
||||
txIndex = 1
|
||||
traceConfig = nil
|
||||
|
||||
contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt())
|
||||
suite.Commit()
|
||||
// Generate token transfer transaction
|
||||
firstTx := suite.TransferERC20Token(suite.T(), contractAddr, suite.address, common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), sdk.NewIntWithDecimal(1, 18).BigInt())
|
||||
txMsg = suite.TransferERC20Token(suite.T(), contractAddr, suite.address, common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), sdk.NewIntWithDecimal(1, 18).BigInt())
|
||||
suite.Commit()
|
||||
|
||||
predecessors = append(predecessors, firstTx)
|
||||
},
|
||||
expPass: true,
|
||||
traceResponse: []byte{0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d},
|
||||
dynamicTxFee: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
@@ -658,9 +687,10 @@ func (suite *KeeperTestSuite) TestTraceTx() {
|
||||
|
||||
tc.malleate()
|
||||
traceReq := types.QueryTraceTxRequest{
|
||||
Msg: txMsg,
|
||||
TraceConfig: traceConfig,
|
||||
TxIndex: 1, // Can be hardcoded as this will be the only tx included in the block
|
||||
Msg: txMsg,
|
||||
TraceConfig: traceConfig,
|
||||
TxIndex: txIndex,
|
||||
Predecessors: predecessors,
|
||||
}
|
||||
res, err := suite.queryClient.TraceTx(ctx, &traceReq)
|
||||
|
||||
@@ -675,3 +705,121 @@ func (suite *KeeperTestSuite) TestTraceTx() {
|
||||
|
||||
suite.dynamicTxFee = false // reset flag
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestTraceBlock() {
|
||||
ctx := sdk.WrapSDKContext(suite.ctx)
|
||||
var (
|
||||
txs []*types.MsgEthereumTx
|
||||
traceConfig *types.TraceConfig
|
||||
)
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
malleate func()
|
||||
expPass bool
|
||||
traceResponse []byte
|
||||
dynamicTxFee bool
|
||||
}{
|
||||
{
|
||||
msg: "default trace",
|
||||
malleate: func() {
|
||||
traceConfig = nil
|
||||
},
|
||||
expPass: true,
|
||||
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x7d, 0x5d},
|
||||
},
|
||||
{
|
||||
msg: "filtered trace",
|
||||
malleate: func() {
|
||||
traceConfig = &types.TraceConfig{
|
||||
DisableStack: true,
|
||||
DisableStorage: true,
|
||||
EnableMemory: false,
|
||||
}
|
||||
},
|
||||
expPass: true,
|
||||
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x7d, 0x5d},
|
||||
}, {
|
||||
msg: "javascript tracer",
|
||||
malleate: func() {
|
||||
traceConfig = &types.TraceConfig{
|
||||
Tracer: "{data: [], fault: function(log) {}, step: function(log) { if(log.op.toString() == \"CALL\") this.data.push(log.stack.peek(0)); }, result: function() { return this.data; }}",
|
||||
}
|
||||
},
|
||||
expPass: true,
|
||||
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x5d},
|
||||
},
|
||||
{
|
||||
msg: "default trace with dynamicTxFee and filtered return",
|
||||
malleate: func() {
|
||||
traceConfig = &types.TraceConfig{
|
||||
DisableStack: true,
|
||||
DisableStorage: true,
|
||||
EnableMemory: false,
|
||||
}
|
||||
},
|
||||
expPass: true,
|
||||
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x7d, 0x5d},
|
||||
dynamicTxFee: true,
|
||||
}, {
|
||||
msg: "javascript tracer with dynamicTxFee",
|
||||
malleate: func() {
|
||||
traceConfig = &types.TraceConfig{
|
||||
Tracer: "{data: [], fault: function(log) {}, step: function(log) { if(log.op.toString() == \"CALL\") this.data.push(log.stack.peek(0)); }, result: function() { return this.data; }}",
|
||||
}
|
||||
},
|
||||
expPass: true,
|
||||
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x5d},
|
||||
dynamicTxFee: true,
|
||||
},
|
||||
{
|
||||
msg: "tracer with multiple transactions",
|
||||
malleate: func() {
|
||||
traceConfig = nil
|
||||
contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt())
|
||||
suite.Commit()
|
||||
// create multiple transactions in the same block
|
||||
firstTx := suite.TransferERC20Token(suite.T(), contractAddr, suite.address, common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), sdk.NewIntWithDecimal(1, 18).BigInt())
|
||||
secondTx := suite.TransferERC20Token(suite.T(), contractAddr, suite.address, common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), sdk.NewIntWithDecimal(1, 18).BigInt())
|
||||
suite.Commit()
|
||||
// overwrite txs to include only the ones on new block
|
||||
txs = append([]*types.MsgEthereumTx{}, firstTx, secondTx)
|
||||
},
|
||||
expPass: true,
|
||||
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x7d, 0x2c, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x7d, 0x5d},
|
||||
dynamicTxFee: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
|
||||
txs = []*types.MsgEthereumTx{}
|
||||
suite.dynamicTxFee = tc.dynamicTxFee
|
||||
suite.SetupTest()
|
||||
// Deploy contract
|
||||
contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt())
|
||||
suite.Commit()
|
||||
// Generate token transfer transaction
|
||||
txMsg := suite.TransferERC20Token(suite.T(), contractAddr, suite.address, common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), sdk.NewIntWithDecimal(1, 18).BigInt())
|
||||
suite.Commit()
|
||||
|
||||
txs = append(txs, txMsg)
|
||||
|
||||
tc.malleate()
|
||||
traceReq := types.QueryTraceBlockRequest{
|
||||
Txs: txs,
|
||||
TraceConfig: traceConfig,
|
||||
}
|
||||
res, err := suite.queryClient.TraceBlock(ctx, &traceReq)
|
||||
|
||||
if tc.expPass {
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().Equal(tc.traceResponse, res.Data)
|
||||
} else {
|
||||
suite.Require().Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
suite.dynamicTxFee = false // reset flag
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user