hermez-node/test/ethclient_test.go
test/ethclient_test.goRaw
1package test
2
3import (
4 "context"
5 "crypto/ecdsa"
6 "encoding/binary"
7 "math/big"
8 "testing"
9 "time"
10
11 ethCommon "github.com/ethereum/go-ethereum/common"
12 ethCrypto "github.com/ethereum/go-ethereum/crypto"
13 "github.com/hermeznetwork/hermez-node/common"
14 "github.com/hermeznetwork/hermez-node/eth"
15 "github.com/iden3/go-iden3-crypto/babyjub"
16 "github.com/stretchr/testify/assert"
17 "github.com/stretchr/testify/require"
18)
19
20type timer struct {
21 time int64
22}
23
24func (t *timer) Time() int64 {
25 currentTime := t.time
26 t.time++
27 return currentTime
28}
29
30func TestClientInterface(t *testing.T) {
31 var c eth.ClientInterface
32 var timer timer
33 clientSetup := NewClientSetupExample()
34 client := NewClient(true, &timer, ðCommon.Address{}, clientSetup)
35 c = client
36 require.NotNil(t, c)
37}
38
39func TestClientEth(t *testing.T) {
40 var timer timer
41 clientSetup := NewClientSetupExample()
42 c := NewClient(true, &timer, ðCommon.Address{}, clientSetup)
43 blockNum, err := c.EthCurrentBlock()
44 require.Nil(t, err)
45 assert.Equal(t, int64(0), blockNum)
46
47 block, err := c.EthBlockByNumber(context.TODO(), 0)
48 require.Nil(t, err)
49 assert.Equal(t, int64(0), block.EthBlockNum)
50 assert.Equal(t, time.Unix(0, 0), block.Timestamp)
51 assert.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000000", block.Hash.Hex())
52 assert.Equal(t, int64(0), c.blockNum)
53
54 // Mine some empty blocks
55
56 c.CtlMineBlock()
57 assert.Equal(t, int64(1), c.blockNum)
58 c.CtlMineBlock()
59 assert.Equal(t, int64(2), c.blockNum)
60
61 block, err = c.EthBlockByNumber(context.TODO(), 2)
62 require.Nil(t, err)
63 assert.Equal(t, int64(2), block.EthBlockNum)
64 assert.Equal(t, time.Unix(2, 0), block.Timestamp)
65}
66
67func TestClientAuction(t *testing.T) {
68 addrBidder1 := ethCommon.HexToAddress("0x6b175474e89094c44da98b954eedeac495271d0f")
69 addrBidder2 := ethCommon.HexToAddress("0xc27cadc437d067a6ec869502cc9f7F834cFc087a")
70 addrForge := ethCommon.HexToAddress("0xCfAA413eEb796f328620a3630Ae39124cabcEa92")
71 addrForge2 := ethCommon.HexToAddress("0x1fCb4ac309428feCc61B1C8cA5823C15A5e1a800")
72
73 var timer timer
74 clientSetup := NewClientSetupExample()
75 clientSetup.AuctionVariables.ClosedAuctionSlots = 2
76 clientSetup.AuctionVariables.OpenAuctionSlots = 4320
77 clientSetup.AuctionVariables.DefaultSlotSetBid = [6]*big.Int{
78 big.NewInt(1000), big.NewInt(1100), big.NewInt(1200),
79 big.NewInt(1300), big.NewInt(1400), big.NewInt(1500)}
80 c := NewClient(true, &timer, &addrBidder1, clientSetup)
81
82 // Check several cases in which bid doesn't succed, and also do 2 successful bids.
83
84 _, err := c.AuctionBid(0, big.NewInt(1))
85 assert.Equal(t, errBidClosed, err)
86
87 _, err = c.AuctionBid(4322, big.NewInt(1))
88 assert.Equal(t, errBidNotOpen, err)
89
90 // 101 % 6 = 5; defaultSlotSetBid[5] = 1500; 1500 + 10% = 1650
91 _, err = c.AuctionBid(101, big.NewInt(1650))
92 assert.Equal(t, errCoordNotReg, err)
93
94 _, err = c.AuctionSetCoordinator(addrForge, "https://foo.bar")
95 assert.Nil(t, err)
96
97 _, err = c.AuctionBid(3, big.NewInt(1))
98 assert.Equal(t, errBidBelowMin, err)
99
100 _, err = c.AuctionBid(3, big.NewInt(1650))
101 assert.Nil(t, err)
102
103 c.CtlSetAddr(addrBidder2)
104 _, err = c.AuctionSetCoordinator(addrForge2, "https://foo2.bar")
105 assert.Nil(t, err)
106
107 _, err = c.AuctionBid(3, big.NewInt(16))
108 assert.Equal(t, errBidBelowMin, err)
109
110 // 1650 + 10% = 1815
111 _, err = c.AuctionBid(3, big.NewInt(1815))
112 assert.Nil(t, err)
113
114 c.CtlMineBlock()
115
116 blockNum, err := c.EthCurrentBlock()
117 require.Nil(t, err)
118
119 auctionEvents, _, err := c.AuctionEventsByBlock(blockNum)
120 require.Nil(t, err)
121 assert.Equal(t, 2, len(auctionEvents.NewBid))
122}
123
124func TestClientRollup(t *testing.T) {
125 token1Addr := ethCommon.HexToAddress("0x6b175474e89094c44da98b954eedeac495271d0f")
126
127 var timer timer
128 clientSetup := NewClientSetupExample()
129 c := NewClient(true, &timer, ðCommon.Address{}, clientSetup)
130
131 // Add a token
132
133 tx, err := c.RollupAddToken(token1Addr)
134 require.Nil(t, err)
135 assert.NotNil(t, tx)
136
137 // Add some L1UserTxs
138 // Create Accounts
139
140 const N = 16
141 var keys [N]*keys
142 for i := 0; i < N; i++ {
143 keys[i] = genKeys(int64(i))
144 l1UserTx := common.L1Tx{
145 FromIdx: nil,
146 FromEthAddr: keys[i].Addr,
147 FromBJJ: keys[i].BJJPublicKey,
148 TokenID: common.TokenID(0),
149 LoadAmount: big.NewInt(10 + int64(i)),
150 }
151 c.CtlAddL1TxUser(&l1UserTx)
152 }
153 c.CtlMineBlock()
154
155 blockNum, err := c.EthCurrentBlock()
156 require.Nil(t, err)
157 rollupEvents, _, err := c.RollupEventsByBlock(blockNum)
158 require.Nil(t, err)
159 assert.Equal(t, N, len(rollupEvents.L1UserTx))
160 assert.Equal(t, 1, len(rollupEvents.AddToken))
161
162 // Forge a batch
163
164 c.CtlAddBatch(ð.RollupForgeBatchArgs{
165 NewLastIdx: 0,
166 NewStRoot: big.NewInt(1),
167 NewExitRoot: big.NewInt(100),
168 L1CoordinatorTxs: []*common.L1Tx{},
169 L2TxsData: []*common.L2Tx{},
170 FeeIdxCoordinator: make([]common.Idx, eth.RollupConstFeeIdxCoordinatorLen),
171 VerifierIdx: 0,
172 L1Batch: true,
173 })
174 c.CtlMineBlock()
175
176 blockNumA, err := c.EthCurrentBlock()
177 require.Nil(t, err)
178 rollupEvents, hashA, err := c.RollupEventsByBlock(blockNumA)
179 require.Nil(t, err)
180 assert.Equal(t, 0, len(rollupEvents.L1UserTx))
181 assert.Equal(t, 0, len(rollupEvents.AddToken))
182 assert.Equal(t, 1, len(rollupEvents.ForgeBatch))
183
184 // Simulate reorg discarding last mined block
185
186 c.CtlRollback()
187 c.CtlMineBlock()
188
189 blockNumB, err := c.EthCurrentBlock()
190 require.Nil(t, err)
191 rollupEvents, hashB, err := c.RollupEventsByBlock(blockNumA)
192 require.Nil(t, err)
193 assert.Equal(t, 0, len(rollupEvents.L1UserTx))
194 assert.Equal(t, 0, len(rollupEvents.AddToken))
195 assert.Equal(t, 0, len(rollupEvents.ForgeBatch))
196
197 assert.Equal(t, blockNumA, blockNumB)
198 assert.NotEqual(t, hashA, hashB)
199
200 // Forge again
201 rollupForgeBatchArgs0 := ð.RollupForgeBatchArgs{
202 NewLastIdx: 0,
203 NewStRoot: big.NewInt(1),
204 NewExitRoot: big.NewInt(100),
205 L1CoordinatorTxs: []*common.L1Tx{},
206 L2TxsData: []*common.L2Tx{},
207 FeeIdxCoordinator: make([]common.Idx, eth.RollupConstFeeIdxCoordinatorLen),
208 VerifierIdx: 0,
209 L1Batch: true,
210 }
211 c.CtlAddBatch(rollupForgeBatchArgs0)
212 c.CtlMineBlock()
213
214 // Retrieve ForgeBatchArguments starting from the events
215
216 blockNum, err = c.EthCurrentBlock()
217 require.Nil(t, err)
218 rollupEvents, _, err = c.RollupEventsByBlock(blockNum)
219 require.Nil(t, err)
220
221 rollupForgeBatchArgs1, err := c.RollupForgeBatchArgs(rollupEvents.ForgeBatch[0].EthTxHash)
222 require.Nil(t, err)
223 assert.Equal(t, rollupForgeBatchArgs0, rollupForgeBatchArgs1)
224}
225
226type keys struct {
227 BJJSecretKey *babyjub.PrivateKey
228 BJJPublicKey *babyjub.PublicKey
229 Addr ethCommon.Address
230}
231
232func genKeys(i int64) *keys {
233 i++ // i = 0 doesn't work for the ecdsa key generation
234 var sk babyjub.PrivateKey
235 binary.LittleEndian.PutUint64(sk[:], uint64(i))
236
237 // eth address
238 var key ecdsa.PrivateKey
239 key.D = big.NewInt(i) // only for testing
240 key.PublicKey.X, key.PublicKey.Y = ethCrypto.S256().ScalarBaseMult(key.D.Bytes())
241 key.Curve = ethCrypto.S256()
242 addr := ethCrypto.PubkeyToAddress(key.PublicKey)
243
244 return &keys{
245 BJJSecretKey: &sk,
246 BJJPublicKey: sk.Public(),
247 Addr: addr,
248 }
249}