-
Notifications
You must be signed in to change notification settings - Fork 0
/
grpc_query.go
150 lines (132 loc) · 4.55 KB
/
grpc_query.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package keeper
import (
"context"
"fmt"
"math/big"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/furyaxyz/elysium/v2/x/elysium/types"
"github.com/ethereum/go-ethereum/common"
evmtypes "github.com/evmos/ethermint/x/evm/types"
)
var _ types.QueryServer = Keeper{}
// ContractByDenom query contract by denom, returns both external contract and auto deployed contract
func (k Keeper) ContractByDenom(goCtx context.Context, req *types.ContractByDenomRequest) (*types.ContractByDenomResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
rsp := types.ContractByDenomResponse{}
contract, found := k.getExternalContractByDenom(ctx, req.Denom)
if found {
rsp.Contract = contract.String()
}
autoContract, found := k.getAutoContractByDenom(ctx, req.Denom)
if found {
rsp.AutoContract = autoContract.String()
}
if len(rsp.Contract) == 0 && len(rsp.AutoContract) == 0 {
return nil, fmt.Errorf("contract for the coin denom %s is not found", req.Denom)
}
return &rsp, nil
}
// DenomByContract query denom by contract
func (k Keeper) DenomByContract(goCtx context.Context, req *types.DenomByContractRequest) (*types.DenomByContractResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
denom, found := k.GetDenomByContract(ctx, common.HexToAddress(req.Contract))
if !found {
return nil, fmt.Errorf("coin denom for contract %s is not found", req.Contract)
}
return &types.DenomByContractResponse{
Denom: denom,
}, nil
}
// ReplayBlock replay the eth messages in the block to recover the results of false-failed txs.
func (k Keeper) ReplayBlock(goCtx context.Context, req *types.ReplayBlockRequest) (*types.ReplayBlockResponse, error) {
rsps := make([]*evmtypes.MsgEthereumTxResponse, 0, len(req.Msgs))
// prepare the block context, the multistore version should be setup already in grpc query context.
ctx := sdk.UnwrapSDKContext(goCtx).
WithBlockHeight(req.BlockNumber).
WithBlockTime(req.BlockTime).
WithHeaderHash(common.Hex2Bytes(req.BlockHash))
// load parameters
params := k.evmKeeper.GetParams(ctx)
chainID := k.evmKeeper.ChainID()
// the chain_id is irrelevant here
ethCfg := params.ChainConfig.EthereumConfig(chainID)
blockHeight := big.NewInt(req.BlockNumber)
homestead := ethCfg.IsHomestead(blockHeight)
istanbul := ethCfg.IsIstanbul(blockHeight)
london := ethCfg.IsLondon(blockHeight)
evmDenom := params.EvmDenom
// we assume the message executions are successful, they are filtered in json-rpc api
for _, msg := range req.Msgs {
// deduct fee
txData, err := evmtypes.UnpackTxData(msg.Data)
if err != nil {
return nil, err
}
// populate the `From` field
if _, err := msg.GetSender(chainID); err != nil {
return nil, err
}
if _, _, err := k.evmKeeper.DeductTxCostsFromUserBalance(
ctx,
*msg,
txData,
evmDenom,
homestead,
istanbul,
london,
); err != nil {
return nil, err
}
// increase nonce
acc := k.accountKeeper.GetAccount(ctx, msg.GetFrom())
if acc == nil {
return nil, fmt.Errorf("account not found %s", msg.From)
}
if err := acc.SetSequence(acc.GetSequence() + 1); err != nil {
return nil, err
}
k.accountKeeper.SetAccount(ctx, acc)
rsp, err := k.evmKeeper.EthereumTx(sdk.WrapSDKContext(ctx), msg)
if err != nil {
return nil, err
}
rsps = append(rsps, rsp)
}
return &types.ReplayBlockResponse{
Responses: rsps,
}, nil
}
// Params returns parameters of elysium module
func (k Keeper) Params(goCtx context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
ctx := sdk.UnwrapSDKContext(goCtx)
params := k.GetParams(ctx)
return &types.QueryParamsResponse{Params: params}, nil
}
// Permissions returns the permissions of a specific account
func (k Keeper) Permissions(goCtx context.Context, req *types.QueryPermissionsRequest) (*types.QueryPermissionsResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
ctx := sdk.UnwrapSDKContext(goCtx)
acc, err := sdk.AccAddressFromBech32(req.Address)
if err != nil {
return nil, err
}
admin := k.GetParams(ctx).ElysiumAdmin
if admin == acc.String() {
return &types.QueryPermissionsResponse{
CanChangeTokenMapping: true,
CanTurnBridge: true,
}, nil
}
permissions := k.GetPermissions(ctx, acc)
return &types.QueryPermissionsResponse{
CanChangeTokenMapping: CanChangeTokenMapping == (permissions & CanChangeTokenMapping),
CanTurnBridge: CanTurnBridge == (permissions & CanTurnBridge),
}, nil
}