-
Notifications
You must be signed in to change notification settings - Fork 0
/
evm_hooks.go
72 lines (63 loc) · 2.01 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
package keeper
import (
"github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
sdk "github.com/brc20-collab/brczero/libs/cosmos-sdk/types"
sdkerror "github.com/brc20-collab/brczero/libs/cosmos-sdk/types/errors"
"github.com/brc20-collab/brczero/x/evm/types"
)
var (
_ types.EvmHooks = MultiEvmHooks{}
_ types.EvmHooks = LogProcessEvmHook{}
)
// MultiEvmHooks combine multiple evm hooks, all hook functions are run in array sequence
type MultiEvmHooks []types.EvmHooks
// NewMultiEvmHooks combine multiple evm hooks
func NewMultiEvmHooks(hooks ...types.EvmHooks) MultiEvmHooks {
return hooks
}
// PostTxProcessing delegate the call to underlying hooks
func (mh MultiEvmHooks) PostTxProcessing(ctx sdk.Context, st *types.StateTransition, receipt *ethtypes.Receipt) error {
for i := range mh {
if err := mh[i].PostTxProcessing(ctx, st, receipt); err != nil {
return sdkerror.Wrapf(err, "EVM hook %T failed", mh[i])
}
}
return nil
}
// LogProcessEvmHook is an evm hook that convert specific contract logs into native module calls
type LogProcessEvmHook struct {
handlers map[common.Hash]types.EvmLogHandler
}
func NewLogProcessEvmHook(handlers ...types.EvmLogHandler) LogProcessEvmHook {
handlerMap := make(map[common.Hash]types.EvmLogHandler)
for _, h := range handlers {
handlerMap[h.EventID()] = h
}
return LogProcessEvmHook{handlerMap}
}
// PostTxProcessing delegate the call to underlying hooks
func (lh LogProcessEvmHook) PostTxProcessing(ctx sdk.Context, st *types.StateTransition, receipt *ethtypes.Receipt) error {
for _, log := range receipt.Logs {
if len(log.Topics) == 0 {
continue
}
if handler, ok := lh.handlers[log.Topics[0]]; ok {
if err := handler.Handle(ctx, log.Address, log.Data); err != nil {
return err
}
}
}
return nil
}
func (lh LogProcessEvmHook) IsCanHooked(logs []*ethtypes.Log) bool {
for _, log := range logs {
if len(log.Topics) == 0 {
continue
}
if _, ok := lh.handlers[log.Topics[0]]; ok {
return true
}
}
return false
}