-
Notifications
You must be signed in to change notification settings - Fork 837
/
evm_hooks.go
116 lines (97 loc) · 3.43 KB
/
evm_hooks.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
// Copyright 2022 Evmos Foundation
// This file is part of the Evmos Network packages.
//
// Evmos is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The Evmos packages are distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the Evmos packages. If not, see https://github.com/evmos/evmos/blob/main/LICENSE
package keeper
import (
"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
ethtypes "github.com/ethereum/go-ethereum/core/types"
evmostypes "github.com/evmos/evmos/v12/types"
evmtypes "github.com/evmos/evmos/v12/x/evm/types"
"github.com/evmos/evmos/v12/x/incentives/types"
)
var _ evmtypes.EvmHooks = Hooks{}
// PostTxProcessing is a wrapper for calling the EVM PostTxProcessing hook on
// the module keeper
func (h Hooks) PostTxProcessing(ctx sdk.Context, msg core.Message, receipt *ethtypes.Receipt) error {
return h.k.PostTxProcessing(ctx, msg, receipt)
}
// PostTxProcessing implements EvmHooks.PostTxProcessing. After each successful
// interaction with an incentivized contract, the participants's GasUsed is
// added to its gasMeter.
func (k Keeper) PostTxProcessing(ctx sdk.Context, msg core.Message, receipt *ethtypes.Receipt) error {
// check if the Incentives are globally enabled
params := k.GetParams(ctx)
if !params.EnableIncentives {
return nil
}
contract := msg.To()
participant := msg.From()
// If theres no incentive registered for the contract, do nothing
if contract == nil || !k.IsIncentiveRegistered(ctx, *contract) {
return nil
}
// safety check: only distribute incentives to EOAs.
acc := k.accountKeeper.GetAccount(ctx, participant.Bytes())
if acc == nil {
return nil
}
ethAccount, ok := acc.(evmostypes.EthAccountI)
if ok && ethAccount.Type() == evmostypes.AccountTypeContract {
return nil
}
k.addGasToIncentive(ctx, *contract, receipt.GasUsed)
k.addGasToParticipant(ctx, *contract, participant, receipt.GasUsed)
defer func() {
telemetry.IncrCounter(
1,
"tx", "msg", "ethereum_tx", types.ModuleName, "total",
)
if receipt.GasUsed != 0 {
telemetry.IncrCounter(
float32(receipt.GasUsed),
"tx", "msg", "ethereum_tx", types.ModuleName, "gas_used", "total",
)
}
}()
return nil
}
// addGasToIncentive adds gasUsed to an incentive's cumulated totalGas
func (k Keeper) addGasToIncentive(
ctx sdk.Context,
contract common.Address,
gasUsed uint64,
) {
// NOTE: existence of contract incentive is already checked
incentive, _ := k.GetIncentive(ctx, contract)
incentive.TotalGas += gasUsed
k.SetIncentive(ctx, incentive)
}
// addGasToParticipant adds gasUsed to a participant's gas meter's cumulative
// gas used
func (k Keeper) addGasToParticipant(
ctx sdk.Context,
contract, participant common.Address,
gasUsed uint64,
) {
previousGas, found := k.GetGasMeter(ctx, contract, participant)
if found {
gasUsed += previousGas
}
gm := types.NewGasMeter(contract, participant, gasUsed)
k.SetGasMeter(ctx, gm)
}