-
Notifications
You must be signed in to change notification settings - Fork 0
/
evm_hooks.go
72 lines (64 loc) · 2.15 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 (
"math/big"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/furyaxyz/elysium/v2/x/elysium/types"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
ethtypes "github.com/ethereum/go-ethereum/core/types"
)
// 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 _, handler := range handlers {
handlerMap[handler.EventID()] = handler
}
return &LogProcessEvmHook{
handlers: handlerMap,
}
}
// PostTxProcessing implements EvmHook interface
func (h LogProcessEvmHook) PostTxProcessing(ctx sdk.Context, msg core.Message, receipt *ethtypes.Receipt) error {
addLogToReceiptFunc := newFuncAddLogToReceipt(receipt)
for _, log := range receipt.Logs {
if len(log.Topics) == 0 {
continue
}
handler, ok := h.handlers[log.Topics[0]]
if !ok {
continue
}
err := handler.Handle(ctx, log.Address, log.Topics, log.Data, addLogToReceiptFunc)
if err != nil {
return err
}
}
return nil
}
// newFuncAddLogToReceipt return a function to add additional logs to the receipt
func newFuncAddLogToReceipt(receipt *ethtypes.Receipt) func(contractAddress common.Address, logSig common.Hash, logData []byte) {
return func(contractAddress common.Address, logSig common.Hash, logData []byte) {
if receipt.BlockNumber == nil {
return
}
newLog := ðtypes.Log{
Address: contractAddress,
Topics: []common.Hash{logSig},
Data: logData,
BlockNumber: receipt.BlockNumber.Uint64(),
TxHash: receipt.TxHash,
TxIndex: receipt.TransactionIndex,
BlockHash: receipt.BlockHash,
Index: uint(len(receipt.Logs)),
Removed: false,
}
// Compute block bloom filter and set to the receipt
bloom := receipt.Bloom.Big()
bloom.Or(bloom, big.NewInt(0).SetBytes(ethtypes.LogsBloom([]*ethtypes.Log{newLog})))
receipt.Bloom = ethtypes.BytesToBloom(bloom.Bytes())
receipt.Logs = append(receipt.Logs, newLog)
}
}