rpc, evm: remove tx Receipt (#81)

* rpc, evm: remove tc receipt

* rm receipt from gRPC query service

* update eth block

* update tx service response

* rpc tx fixes

* update bloom

* fix

* more fixes

* c++
This commit is contained in:
Federico Kunze
2021-06-08 07:11:37 -04:00
committed by GitHub
parent e3270aee5d
commit 6eadc8fdf8
27 changed files with 458 additions and 1820 deletions
-38
View File
@@ -203,44 +203,6 @@ func (k Keeper) TxLogs(c context.Context, req *types.QueryTxLogsRequest) (*types
}, nil
}
// TxReceipt implements the Query/TxReceipt gRPC method
func (k Keeper) TxReceipt(c context.Context, req *types.QueryTxReceiptRequest) (*types.QueryTxReceiptResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if ethermint.IsEmptyHash(req.Hash) {
return nil, status.Error(
codes.InvalidArgument,
types.ErrEmptyHash.Error(),
)
}
ctx := sdk.UnwrapSDKContext(c)
hash := ethcmn.HexToHash(req.Hash)
receipt, found := k.GetTxReceiptFromHash(ctx, hash)
if !found {
return nil, status.Errorf(
codes.NotFound, "%s: %s", types.ErrTxReceiptNotFound.Error(), req.Hash,
)
}
return &types.QueryTxReceiptResponse{
Receipt: receipt,
}, nil
}
// TxReceiptsByBlockHeight implements the Query/TxReceiptsByBlockHeight gRPC method
func (k Keeper) TxReceiptsByBlockHeight(c context.Context, _ *types.QueryTxReceiptsByBlockHeightRequest) (*types.QueryTxReceiptsByBlockHeightResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
receipts := k.GetTxReceiptsByBlockHeight(ctx, uint64(ctx.BlockHeight()))
return &types.QueryTxReceiptsByBlockHeightResponse{
Receipts: receipts,
}, nil
}
// BlockLogs implements the Query/BlockLogs gRPC method
func (k Keeper) BlockLogs(c context.Context, req *types.QueryBlockLogsRequest) (*types.QueryBlockLogsResponse, error) {
if req == nil {
-130
View File
@@ -517,136 +517,6 @@ func (suite *KeeperTestSuite) TestQueryBlockLogs() {
}
}
func (suite *KeeperTestSuite) TestQueryTxReceipt() {
var (
req *types.QueryTxReceiptRequest
expRes *types.QueryTxReceiptResponse
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{"empty hash",
func() {
req = &types.QueryTxReceiptRequest{}
},
false,
},
{"tx receipt not found for hash",
func() {
hash := ethcmn.BytesToHash([]byte("thash"))
req = &types.QueryTxReceiptRequest{
Hash: hash.Hex(),
}
},
false,
},
{"success",
func() {
hash := ethcmn.BytesToHash([]byte("thash"))
receipt := &types.TxReceipt{
Hash: hash.Hex(),
From: suite.address.Hex(),
BlockHeight: uint64(suite.ctx.BlockHeight()),
BlockHash: ethcmn.BytesToHash(suite.ctx.BlockHeader().DataHash).Hex(),
}
suite.app.EvmKeeper.SetTxReceiptToHash(suite.ctx, hash, receipt)
req = &types.QueryTxReceiptRequest{
Hash: hash.Hex(),
}
expRes = &types.QueryTxReceiptResponse{
Receipt: receipt,
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset
tc.malleate()
ctx := sdk.WrapSDKContext(suite.ctx)
res, err := suite.queryClient.TxReceipt(ctx, req)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expRes, res)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestQueryTxReceiptByBlockHeight() {
var (
req = &types.QueryTxReceiptsByBlockHeightRequest{}
expRes *types.QueryTxReceiptsByBlockHeightResponse
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{"empty response",
func() {
expRes = &types.QueryTxReceiptsByBlockHeightResponse{
Receipts: nil,
}
},
true,
},
{"success",
func() {
hash := ethcmn.BytesToHash([]byte("thash"))
receipt := &types.TxReceipt{
Hash: hash.Hex(),
From: suite.address.Hex(),
BlockHeight: uint64(suite.ctx.BlockHeight()),
BlockHash: ethcmn.BytesToHash(suite.ctx.BlockHeader().DataHash).Hex(),
}
suite.app.EvmKeeper.AddTxHashToBlock(suite.ctx, suite.ctx.BlockHeight(), hash)
suite.app.EvmKeeper.SetTxReceiptToHash(suite.ctx, hash, receipt)
expRes = &types.QueryTxReceiptsByBlockHeightResponse{
Receipts: []*types.TxReceipt{receipt},
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset
tc.malleate()
ctx := sdk.WrapSDKContext(suite.ctx)
ctx = metadata.AppendToOutgoingContext(ctx, grpctypes.GRPCBlockHeightHeader, fmt.Sprintf("%d", suite.ctx.BlockHeight()))
res, err := suite.queryClient.TxReceiptsByBlockHeight(ctx, req)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expRes, res)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestQueryBlockBloom() {
var (
req *types.QueryBlockBloomRequest
-93
View File
@@ -144,20 +144,6 @@ func (k Keeper) SetBlockBloomTransient(bloom *big.Int) {
store.Set(types.KeyPrefixTransientBloom, bloom.Bytes())
}
// ----------------------------------------------------------------------------
// Block
// ----------------------------------------------------------------------------
// SetTxReceiptToHash sets the mapping from tx hash to tx receipt
func (k Keeper) SetTxReceiptToHash(ctx sdk.Context, hash common.Hash, receipt *types.TxReceipt) {
ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
data := k.cdc.MustMarshalBinaryBare(receipt)
store := ctx.KVStore(k.storeKey)
store.Set(types.KeyHashTxReceipt(hash), data)
}
// ----------------------------------------------------------------------------
// Tx
// ----------------------------------------------------------------------------
@@ -187,85 +173,6 @@ func (k Keeper) ResetRefundTransient(ctx sdk.Context) {
store.Delete(types.KeyPrefixTransientRefund)
}
// GetTxReceiptFromHash gets tx receipt by tx hash.
func (k Keeper) GetTxReceiptFromHash(ctx sdk.Context, hash common.Hash) (*types.TxReceipt, bool) {
store := ctx.KVStore(k.storeKey)
data := store.Get(types.KeyHashTxReceipt(hash))
if len(data) == 0 {
return nil, false
}
var receipt types.TxReceipt
k.cdc.MustUnmarshalBinaryBare(data, &receipt)
return &receipt, true
}
// AddTxHashToBlock stores tx hash in the list of tx for the block.
func (k Keeper) AddTxHashToBlock(ctx sdk.Context, blockHeight int64, txHash common.Hash) {
key := types.KeyBlockHeightTxs(uint64(blockHeight))
list := types.BytesList{}
store := ctx.KVStore(k.storeKey)
data := store.Get(key)
if len(data) > 0 {
k.cdc.MustUnmarshalBinaryBare(data, &list)
}
list.Bytes = append(list.Bytes, txHash.Bytes())
data = k.cdc.MustMarshalBinaryBare(&list)
store.Set(key, data)
}
// GetTxsFromBlock returns list of tx hash in the block by height.
func (k Keeper) GetTxsFromBlock(ctx sdk.Context, blockHeight uint64) []common.Hash {
key := types.KeyBlockHeightTxs(blockHeight)
store := ctx.KVStore(k.storeKey)
data := store.Get(key)
if len(data) > 0 {
list := types.BytesList{}
k.cdc.MustUnmarshalBinaryBare(data, &list)
txs := make([]common.Hash, 0, len(list.Bytes))
for _, b := range list.Bytes {
txs = append(txs, common.BytesToHash(b))
}
return txs
}
return nil
}
// GetTxReceiptsByBlockHeight gets tx receipts by block height.
func (k Keeper) GetTxReceiptsByBlockHeight(ctx sdk.Context, blockHeight uint64) []*types.TxReceipt {
txs := k.GetTxsFromBlock(ctx, blockHeight)
if len(txs) == 0 {
return nil
}
store := ctx.KVStore(k.storeKey)
receipts := make([]*types.TxReceipt, 0, len(txs))
for idx, txHash := range txs {
data := store.Get(types.KeyHashTxReceipt(txHash))
if len(data) == 0 {
continue
}
var receipt types.TxReceipt
k.cdc.MustUnmarshalBinaryBare(data, &receipt)
receipt.Index = uint64(idx)
receipts = append(receipts, &receipt)
}
return receipts
}
// ----------------------------------------------------------------------------
// Log
// ----------------------------------------------------------------------------
+8 -45
View File
@@ -8,6 +8,7 @@ import (
"github.com/armon/go-metrics"
ethcmn "github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
tmtypes "github.com/tendermint/tendermint/types"
@@ -55,6 +56,9 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t
txHash := tmtypes.Tx(ctx.TxBytes()).Hash()
ethHash := ethcmn.BytesToHash(txHash)
// Ethereum formatted tx hash
etherumTxHash := msg.AsTransaction().Hash()
st := &types.StateTransition{
Message: ethMsg,
Csdb: k.CommitStateDB.WithContext(ctx),
@@ -77,25 +81,6 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t
if errors.Is(err, vm.ErrExecutionReverted) && executionResult != nil {
// keep the execution result for revert reason
executionResult.Response.Reverted = true
if !st.Simulate {
k.SetTxReceiptToHash(ctx, ethHash, &types.TxReceipt{
Hash: ethHash.Hex(),
From: sender.Hex(),
Data: msg.Data,
BlockHeight: uint64(ctx.BlockHeight()),
BlockHash: k.headerHash.Hex(),
Result: &types.TxResult{
ContractAddress: executionResult.Response.ContractAddress,
Bloom: executionResult.Response.Bloom,
TxLogs: executionResult.Response.TxLogs,
Ret: executionResult.Response.Ret,
Reverted: executionResult.Response.Reverted,
GasUsed: executionResult.GasInfo.GasConsumed,
},
})
}
return executionResult.Response, nil
}
@@ -108,33 +93,9 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t
bloom = big.NewInt(0)
}
// update block bloom filter
bloom = bloom.Or(bloom, executionResult.Bloom)
logsBloom := ethtypes.LogsBloom(executionResult.Logs)
bloom = bloom.Or(bloom, new(big.Int).SetBytes(logsBloom))
k.SetBlockBloomTransient(bloom)
// update transaction logs in KVStore
err = k.CommitStateDB.SetLogs(ethHash, executionResult.Logs)
if err != nil {
panic(err)
}
k.SetTxReceiptToHash(ctx, ethHash, &types.TxReceipt{
Hash: ethHash.Hex(),
From: sender.Hex(),
Data: msg.Data,
Index: uint64(st.Csdb.TxIndex()),
BlockHeight: uint64(ctx.BlockHeight()),
BlockHash: k.headerHash.Hex(),
Result: &types.TxResult{
ContractAddress: executionResult.Response.ContractAddress,
Bloom: executionResult.Response.Bloom,
TxLogs: executionResult.Response.TxLogs,
Ret: executionResult.Response.Ret,
Reverted: executionResult.Response.Reverted,
GasUsed: executionResult.GasInfo.GasConsumed,
},
})
k.AddTxHashToBlock(ctx, ctx.BlockHeight(), ethHash)
}
defer func() {
@@ -155,6 +116,7 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t
attrs := []sdk.Attribute{
sdk.NewAttribute(sdk.AttributeKeyAmount, st.Message.Value().String()),
sdk.NewAttribute(types.AttributeKeyTxHash, ethcmn.BytesToHash(txHash).Hex()),
sdk.NewAttribute(types.AttributeKeyEthereumTxHash, etherumTxHash.Hex()),
}
if len(msg.Data.To) > 0 {
@@ -174,5 +136,6 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t
),
})
executionResult.Response.Hash = etherumTxHash.Hex()
return executionResult.Response, nil
}
+4 -8
View File
@@ -145,10 +145,8 @@ func (k *Keeper) TransitionDb(msg core.Message) (*types.ExecutionResult, error)
func (k *Keeper) ApplyMessage(evm *vm.EVM, msg core.Message) (*types.ExecutionResult, error) {
var (
ret []byte // return bytes from evm execution
contract common.Address
contractAddr string
vmErr, err error // vm errors do not effect consensus and are therefore not assigned to err
ret []byte // return bytes from evm execution
vmErr, err error // vm errors do not effect consensus and are therefore not assigned to err
)
sender := vm.AccountRef(msg.From())
@@ -174,8 +172,7 @@ func (k *Keeper) ApplyMessage(evm *vm.EVM, msg core.Message) (*types.ExecutionRe
}
if contractCreation {
ret, contract, leftoverGas, vmErr = evm.Create(sender, msg.Data(), leftoverGas, msg.Value())
contractAddr = contract.Hex()
ret, _, leftoverGas, vmErr = evm.Create(sender, msg.Data(), leftoverGas, msg.Value())
} else {
ret, leftoverGas, vmErr = evm.Call(sender, *msg.To(), msg.Data(), leftoverGas, msg.Value())
}
@@ -198,8 +195,7 @@ func (k *Keeper) ApplyMessage(evm *vm.EVM, msg core.Message) (*types.ExecutionRe
return &types.ExecutionResult{
Response: &types.MsgEthereumTxResponse{
ContractAddress: contractAddr,
Ret: ret,
Ret: ret,
},
GasInfo: types.GasInfo{
GasLimit: k.ctx.GasMeter().Limit(),