@@ -11,6 +11,7 @@ import (
11
11
ethereum "github.com/celo-org/celo-blockchain"
12
12
"github.com/celo-org/celo-blockchain/common"
13
13
"github.com/celo-org/celo-blockchain/common/hexutil"
14
+ "github.com/celo-org/celo-blockchain/core"
14
15
"github.com/celo-org/celo-blockchain/core/types"
15
16
"github.com/celo-org/celo-blockchain/ethclient"
16
17
"github.com/celo-org/celo-blockchain/internal/ethapi"
@@ -31,7 +32,191 @@ const (
31
32
func TestTransferCELO (t * testing.T ) {
32
33
ac := test .AccountConfig (1 , 3 )
33
34
gc , ec , err := test .BuildConfig (ac )
34
- gc .Hardforks .EspressoBlock = big .NewInt (0 )
35
+ require .NoError (t , err )
36
+ network , shutdown , err := test .NewNetwork (ac , gc , ec )
37
+ require .NoError (t , err )
38
+ defer shutdown ()
39
+ ctx , cancel := context .WithTimeout (context .Background (), time .Second * 30 )
40
+ defer cancel ()
41
+
42
+ node := network [0 ] // validator node
43
+ client := node .WsClient
44
+ devAccounts := test .Accounts (ac .DeveloperAccounts (), gc .ChainConfig ())
45
+ sender := devAccounts [0 ]
46
+ recipient := devAccounts [1 ]
47
+ gateWayFeeRecipient := devAccounts [2 ]
48
+
49
+ // Get datum to set GasPrice/MaxFeePerGas/MaxPriorityFeePerGas to sensible values
50
+ header , err := network [0 ].WsClient .HeaderByNumber (ctx , common .Big0 )
51
+ require .NoError (t , err )
52
+ datum , err := network [0 ].Eth .APIBackend .GasPriceMinimumForHeader (ctx , nil , header )
53
+ require .NoError (t , err )
54
+
55
+ testCases := []struct {
56
+ name string
57
+ txArgs * ethapi.TransactionArgs
58
+ expectedErr error
59
+ }{
60
+ {
61
+ name : "eth compatible LegacyTxType" ,
62
+ txArgs : & ethapi.TransactionArgs {
63
+ To : & recipient .Address ,
64
+ Value : (* hexutil .Big )(new (big.Int ).SetInt64 (oneCelo )),
65
+ GasPrice : (* hexutil .Big )(datum .Mul (datum , new (big.Int ).SetInt64 (4 ))),
66
+ },
67
+ expectedErr : nil ,
68
+ },
69
+ {
70
+ name : "eth incompatible LegacyTxType" ,
71
+ txArgs : & ethapi.TransactionArgs {
72
+ To : & recipient .Address ,
73
+ Value : (* hexutil .Big )(new (big.Int ).SetInt64 (oneCelo )),
74
+ GasPrice : (* hexutil .Big )(datum .Mul (datum , new (big.Int ).SetInt64 (4 ))),
75
+ GatewayFee : (* hexutil .Big )(new (big.Int ).SetInt64 (oneCelo / 10 )),
76
+ GatewayFeeRecipient : & gateWayFeeRecipient .Address ,
77
+ },
78
+ expectedErr : core .ErrGatewayFeeDeprecated ,
79
+ },
80
+ {
81
+ name : "AccessListTxType" ,
82
+ txArgs : & ethapi.TransactionArgs {
83
+ To : & recipient .Address ,
84
+ Value : (* hexutil .Big )(new (big.Int ).SetInt64 (oneCelo )),
85
+ GasPrice : (* hexutil .Big )(datum .Mul (datum , new (big.Int ).SetInt64 (4 ))),
86
+ AccessList : & types.AccessList {},
87
+ },
88
+ expectedErr : nil ,
89
+ },
90
+ {
91
+ name : "DynamicFeeTxType - tip = MaxFeePerGas - BaseFee" ,
92
+ txArgs : & ethapi.TransactionArgs {
93
+ To : & recipient .Address ,
94
+ Value : (* hexutil .Big )(new (big.Int ).SetInt64 (oneCelo )),
95
+ MaxFeePerGas : (* hexutil .Big )(datum .Mul (datum , new (big.Int ).SetInt64 (4 ))),
96
+ MaxPriorityFeePerGas : (* hexutil .Big )(datum .Mul (datum , new (big.Int ).SetInt64 (4 ))),
97
+ },
98
+ expectedErr : nil ,
99
+ },
100
+ {
101
+ name : "DynamicFeeTxType - tip = MaxPriorityFeePerGas" ,
102
+ txArgs : & ethapi.TransactionArgs {
103
+ To : & recipient .Address ,
104
+ Value : (* hexutil .Big )(new (big.Int ).SetInt64 (oneCelo )),
105
+ MaxFeePerGas : (* hexutil .Big )(datum .Mul (datum , new (big.Int ).SetInt64 (4 ))),
106
+ MaxPriorityFeePerGas : (* hexutil .Big )(datum ),
107
+ },
108
+ expectedErr : nil ,
109
+ },
110
+ {
111
+ name : "CeloDynamicFeeTxType - gas = MaxFeePerGas - BaseFee" ,
112
+ txArgs : & ethapi.TransactionArgs {
113
+ To : & recipient .Address ,
114
+ Value : (* hexutil .Big )(new (big.Int ).SetInt64 (oneCelo )),
115
+ MaxFeePerGas : (* hexutil .Big )(datum .Mul (datum , new (big.Int ).SetInt64 (4 ))),
116
+ MaxPriorityFeePerGas : (* hexutil .Big )(datum .Mul (datum , new (big.Int ).SetInt64 (4 ))),
117
+ GatewayFee : (* hexutil .Big )(new (big.Int ).SetInt64 (oneCelo / 10 )),
118
+ GatewayFeeRecipient : & gateWayFeeRecipient .Address ,
119
+ },
120
+ expectedErr : core .ErrGatewayFeeDeprecated ,
121
+ },
122
+ {
123
+ name : "CeloDynamicFeeTxType - MaxPriorityFeePerGas" ,
124
+ txArgs : & ethapi.TransactionArgs {
125
+ To : & recipient .Address ,
126
+ Value : (* hexutil .Big )(new (big.Int ).SetInt64 (oneCelo )),
127
+ MaxFeePerGas : (* hexutil .Big )(datum .Mul (datum , new (big.Int ).SetInt64 (4 ))),
128
+ MaxPriorityFeePerGas : (* hexutil .Big )(datum ),
129
+ GatewayFee : (* hexutil .Big )(new (big.Int ).SetInt64 (oneCelo / 10 )),
130
+ GatewayFeeRecipient : & gateWayFeeRecipient .Address ,
131
+ },
132
+ expectedErr : core .ErrGatewayFeeDeprecated ,
133
+ },
134
+ }
135
+
136
+ for _ , tc := range testCases {
137
+ t .Run (tc .name , func (t * testing.T ) {
138
+ watcher := test .NewBalanceWatcher (client , []common.Address {sender .Address , recipient .Address , gateWayFeeRecipient .Address , node .Address })
139
+ blockNum , err := client .BlockNumber (ctx )
140
+ require .NoError (t , err )
141
+ signer := types .MakeSigner (devAccounts [0 ].ChainConfig , new (big.Int ).SetUint64 (blockNum ))
142
+ tx , err := prepareTransaction (* tc .txArgs , sender .Key , sender .Address , signer , client )
143
+ require .NoError (t , err )
144
+ err = client .SendTransaction (ctx , tx )
145
+ if tc .expectedErr != nil {
146
+ // Once the error is checked, there's nothing more to do
147
+ if err .Error () != tc .expectedErr .Error () {
148
+ t .Error ("Expected error" , tc .expectedErr , "got" , err )
149
+ }
150
+ return
151
+ }
152
+
153
+ require .NoError (t , err , "SendTransaction failed" , "tx" , * tx )
154
+ err = network .AwaitTransactions (ctx , tx )
155
+ require .NoError (t , err )
156
+ watcher .Update ()
157
+ receipt , err := client .TransactionReceipt (ctx , tx .Hash ())
158
+ require .NoError (t , err )
159
+
160
+ // check value goes to recipient
161
+ expected := tx .Value ()
162
+ actual := watcher .Delta (recipient .Address )
163
+ assert .Equal (t , expected , actual , "Recipient's balance increase unexpected" , "expected" , expected .Int64 (), "actual" , actual .Int64 ())
164
+
165
+ // Check tip goes to validator
166
+ header , err := network [0 ].WsClient .HeaderByNumber (ctx , receipt .BlockNumber )
167
+ require .NoError (t , err )
168
+ gpm , err := network [0 ].Eth .APIBackend .GasPriceMinimumForHeader (ctx , nil , header )
169
+ require .NoError (t , err )
170
+ baseFee := new (big.Int ).Mul (gpm , new (big.Int ).SetUint64 (receipt .GasUsed ))
171
+ switch tx .Type () {
172
+ case types .LegacyTxType , types .AccessListTxType :
173
+ fee := new (big.Int ).Mul (tx .GasPrice (), new (big.Int ).SetUint64 (receipt .GasUsed ))
174
+ expected = new (big.Int ).Sub (fee , baseFee )
175
+ case types .DynamicFeeTxType , types .CeloDynamicFeeTxType :
176
+ expected = tx .EffectiveGasTipValue (gpm )
177
+ expected .Mul (expected , new (big.Int ).SetUint64 (receipt .GasUsed ))
178
+ }
179
+ actual = watcher .Delta (node .Address )
180
+ assert .Equal (t , expected , actual , "Validator's balance increase unexpected" , "expected" , expected .Int64 (), "actual" , actual .Int64 ())
181
+
182
+ // check value + tx fee + gateway fee are subtracted from sender
183
+ var fee * big.Int
184
+ switch tx .Type () {
185
+ case types .LegacyTxType , types .AccessListTxType :
186
+ fee = new (big.Int ).Mul (tx .GasPrice (), new (big.Int ).SetUint64 (receipt .GasUsed ))
187
+ case types .DynamicFeeTxType , types .CeloDynamicFeeTxType :
188
+ tip := tx .EffectiveGasTipValue (gpm )
189
+ tip .Mul (tip , new (big.Int ).SetUint64 (receipt .GasUsed ))
190
+ fee = new (big.Int ).Add (tip , baseFee )
191
+ }
192
+ consumed := new (big.Int ).Add (tx .Value (), fee )
193
+ if tx .GatewayFeeRecipient () != nil && tx .GatewayFee () != nil {
194
+ consumed .Add (consumed , tx .GatewayFee ())
195
+ }
196
+ expected = new (big.Int ).Neg (consumed )
197
+ actual = watcher .Delta (sender .Address )
198
+ assert .Equal (t , expected , actual , "Sender's balance decrease unexpected" , "expected" , expected .Int64 (), "actual" , expected .Int64 ())
199
+
200
+ // Check gateway fee
201
+ if tx .GatewayFeeRecipient () != nil && tx .GatewayFee () != nil {
202
+ expected = tx .GatewayFee ()
203
+ actual = watcher .Delta (gateWayFeeRecipient .Address )
204
+ assert .Equal (t , expected , actual , "gateWayFeeRecipient's balance increase unexpected" , "expected" , expected .Int64 (), "actual" , actual .Int64 ())
205
+ }
206
+ })
207
+ }
208
+ }
209
+
210
+ // TestTransferCELO checks following accounts:
211
+ // - Sender account has transfer value, transaction fee deducted
212
+ // - Receiver account has transfer value added.
213
+ // - Governance account has base fee added.
214
+ // - validator account has tip fee added.
215
+ func TestTransferCELOPreGFork (t * testing.T ) {
216
+ ac := test .AccountConfig (1 , 3 )
217
+ gc , ec , err := test .BuildConfig (ac )
218
+ gc .Hardforks .GForkBlock = nil
219
+
35
220
require .NoError (t , err )
36
221
network , shutdown , err := test .NewNetwork (ac , gc , ec )
37
222
require .NoError (t , err )
0 commit comments