-
Notifications
You must be signed in to change notification settings - Fork 0
/
ante.go
155 lines (139 loc) · 4.94 KB
/
ante.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
151
152
153
154
155
package ante
import (
sdk "github.com/ci123chain/ci123chain/pkg/abci/types"
"github.com/ci123chain/ci123chain/pkg/account"
types2 "github.com/ci123chain/ci123chain/pkg/app/types"
"github.com/ci123chain/ci123chain/pkg/auth"
"github.com/ci123chain/ci123chain/pkg/cryptosuite"
"math/big"
sdkerrors "github.com/ci123chain/ci123chain/pkg/abci/types/errors"
"github.com/ci123chain/ci123chain/pkg/supply"
"github.com/ci123chain/ci123chain/pkg/util"
)
const (
GasSimulateCost sdk.Gas = 200
)
var simSecp256k1Sig [65]byte
//const unit = 1000
func NewAnteHandler( authKeeper auth.AuthKeeper, ak account.AccountKeeper, sk supply.Keeper) sdk.AnteHandler {
return func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, res sdk.Result, err error, abort bool) {
if simulate {
params := authKeeper.GetParams(ctx)
newCtx = SetGasMeter(simulate, ctx, 0)
tx.SetSignature(simSecp256k1Sig[:])
newCtx.GasMeter().ConsumeGas(params.TxSizeCostPerByte*sdk.Gas(len(tx.Bytes())), "txSize")
newCtx.GasMeter().ConsumeGas(GasSimulateCost, "simulate cost")
return
}
var signer sdk.AccAddress
//check sign
if etx, ok := tx.(*types2.MsgEthereumTx); ok {
from, err := etx.VerifySig(big.NewInt(util.CHAINID))
if err != nil {
return newCtx, sdk.Result{}, sdkerrors.ErrorInvalidSigner, true
}
signer = sdk.HexToAddress(from.String())
} else {
eth := cryptosuite.NewEccK1()
valid, err := eth.Verify(tx.GetFromAddress().Bytes(), tx.GetSignBytes(), tx.GetSignature())
if !valid || err != nil {
return newCtx, sdk.Result{}, sdkerrors.ErrorInvalidSigner, true
}
signer = tx.GetFromAddress()
}
acc := ak.GetAccount(ctx, signer)
if acc == nil {
newCtx := ctx.WithGasMeter(sdk.NewGasMeter(0))
return newCtx, sdk.Result{}, sdkerrors.ErrAccountNotExist, true
}
params := authKeeper.GetParams(ctx)
// Ensure that the provided fees meet a minimum threshold for the validator,
// if this is a CheckTx. This is only for local mempool purposes, and thus
// is only ran on check tx.
if ctx.IsCheckTx() && !simulate {
res := EnsureSufficientMempoolFees()
if !res.IsOK() {
return newCtx, res, sdkerrors.ErrInsufficientMempoolFess, true
}
}
gas := tx.GetGas()//用户期望的gas值 g.limit
newCtx = SetGasMeter(simulate, ctx, gas)//设置为GasMeter的gasLimit,成为用户可承受的gas上限.
//检查是否足够支付gas limit, 并预先扣除
gasTotal := sdk.CalculateGas(gas)
if err := sk.SendCoinsFromAccountToModule(newCtx, signer, auth.FeeCollectorName, sdk.NewCoins(sdk.NewChainCoin(gasTotal))); err != nil {
return newCtx, sdk.Result{}, err, true
}
//Calculate fee of tx size
newCtx.GasMeter().ConsumeGas(params.TxSizeCostPerByte * sdk.Gas(len(newCtx.TxBytes())), "txSize")
// account sequence{nonce} + 1
if !ctx.IsCheckTx() {
accountSequence := acc.GetSequence()
txNonce := tx.GetNonce()
if txNonce != accountSequence {
newCtx := ctx.WithGasMeter(sdk.NewGasMeter(0))
return newCtx, sdk.Result{}, sdkerrors.ErrInvalidParam.Wrap("nonce dismatch"), true
}
acc = ak.GetAccount(ctx, signer)
nowSequence := accountSequence + 1
_ = acc.SetSequence(nowSequence)
ak.SetAccount(newCtx, acc)
}
return newCtx, sdk.Result{GasWanted:gas, GasUsed: newCtx.GasMeter().GasConsumed()}, nil, false
}
}
func SetGasMeter(simulate bool, ctx sdk.Context, gaslimit uint64) sdk.Context {
if simulate || ctx.BlockHeight() == 0 {
return ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
}
return ctx.WithGasMeter(sdk.NewGasMeter(gaslimit))
}
func EnsureSufficientMempoolFees() sdk.Result {
//minGasPrices := ctx.MinGasPrices()
//if !minGasPrices.IsZero() {
// requiredFees := make(sdk.Coins, len(minGasPrices))
//
// // Determine the required fees by multiplying each required minimum gas
// // price by the gas limit, where fee = ceil(minGasPrice * gasLimit).
// glDec := sdk.NewDec(int64(stdFee.Gas))
// for i, gp := range minGasPrices {
// fee := gp.Amount.Mul(glDec)
// requiredFees[i] = sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt())
// }
//
// if !stdFee.Amount.IsAnyGTE(requiredFees) {
// return sdk.ErrInsufficientFee(
// fmt.Sprintf(
// "insufficient fees; got: %q required: %q", stdFee.Amount, requiredFees,
// ),
// ).Result()
// }
//}
return sdk.Result{}
}
//
//func DeductFees(acc exported.Account, fee sdk.Coin, ak account.AccountKeeper, ctx sdk.Context) error{
// coin := acc.GetCoins()
// newCoins, hasNeg := coin.SafeSub(sdk.NewCoins(fee))
// if hasNeg {
// return sdkerrors.ErrInsufficientFunds
// }
//
// if err := acc.SetCoins(newCoins); err != nil {
// return sdkerrors.ErrAccountSetCoinFailed
// }
// ak.SetAccount(ctx, acc)
//
// return nil
//}
//
//func ReturnFees(acc exported.Account, restFee sdk.Coins, ak account.AccountKeeper, ctx sdk.Context) error {
// coin := acc.GetCoins()
// newCoins:= coin.Add(restFee)
//
// if err := acc.SetCoins(newCoins); err != nil {
// return sdkerrors.ErrAccountSetCoinFailed
// }
// ak.SetAccount(ctx, acc)
//
// return nil
//}