-
Notifications
You must be signed in to change notification settings - Fork 175
/
call.go
131 lines (117 loc) · 3.35 KB
/
call.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
package types
import (
"math/big"
gethCommon "github.com/ethereum/go-ethereum/common"
gethCore "github.com/ethereum/go-ethereum/core"
gethCrypto "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp"
)
const (
// tx type 255 is used for direct calls from bridged accounts
DirectCallTxType = byte(255)
UnknownCallSubType = byte(0)
DepositCallSubType = byte(1)
WithdrawCallSubType = byte(2)
TransferCallSubType = byte(3)
DeployCallSubType = byte(4)
ContractCallSubType = byte(5)
TransferGasUsage = 21_000
)
// DirectCall captures all the data related to a direct call to evm
// direct calls are similar to transactions but they don't have
// signatures and don't need sequence number checks
type DirectCall struct {
Type byte
SubType byte
From Address
To Address
Data []byte
Value *big.Int
GasLimit uint64
}
// Encode encodes the direct call it also adds the type
// as the very first byte, similar to how evm encodes types.
func (dc *DirectCall) Encode() ([]byte, error) {
encoded, err := rlp.EncodeToBytes(dc)
return append([]byte{dc.Type}, encoded...), err
}
// Hash computes the hash of a direct call
func (dc *DirectCall) Hash() (gethCommon.Hash, error) {
encoded, err := dc.Encode()
return gethCrypto.Keccak256Hash(encoded), err
}
// Message constructs a core.Message from the direct call
func (dc *DirectCall) Message() *gethCore.Message {
var to *gethCommon.Address
if dc.To != EmptyAddress {
ct := dc.To.ToCommon()
to = &ct
}
return &gethCore.Message{
From: dc.From.ToCommon(),
To: to,
Value: dc.Value,
Data: dc.Data,
GasLimit: dc.GasLimit,
GasPrice: big.NewInt(0), // price is set to zero fo direct calls
GasTipCap: big.NewInt(1), // also known as maxPriorityFeePerGas
GasFeeCap: big.NewInt(2), // also known as maxFeePerGas
// AccessList: tx.AccessList(), // TODO revisit this value, the cost matter but performance might
SkipAccountChecks: true, // this would let us not set the nonce
}
}
func NewDepositCall(address Address, amount *big.Int) *DirectCall {
return &DirectCall{
Type: DirectCallTxType,
SubType: DepositCallSubType,
From: EmptyAddress,
To: address,
Data: nil,
Value: amount,
GasLimit: TransferGasUsage,
}
}
func NewWithdrawCall(address Address, amount *big.Int) *DirectCall {
return &DirectCall{
Type: DirectCallTxType,
SubType: WithdrawCallSubType,
From: address,
To: EmptyAddress,
Data: nil,
Value: amount,
GasLimit: TransferGasUsage,
}
}
func NewTransferCall(from Address, to Address, amount *big.Int) *DirectCall {
return &DirectCall{
Type: DirectCallTxType,
SubType: TransferCallSubType,
From: from,
To: to,
Data: nil,
Value: amount,
GasLimit: TransferGasUsage,
}
}
func NewDeployCall(caller Address, code Code, gasLimit uint64, value *big.Int) *DirectCall {
return &DirectCall{
Type: DirectCallTxType,
SubType: DeployCallSubType,
From: caller,
To: EmptyAddress,
Data: code,
Value: value,
GasLimit: gasLimit,
}
}
func NewContractCall(caller Address, to Address, data Data, gasLimit uint64, value *big.Int) *DirectCall {
return &DirectCall{
Type: DirectCallTxType,
SubType: ContractCallSubType,
From: caller,
To: to,
Data: data,
Value: value,
GasLimit: gasLimit,
}
}