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, ethCommon.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, ethCommon.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 addrWithdraw := ethCommon.HexToAddress("0x6b175474e89094c44da98b954eedeac495271d0f")
69 addrForge := ethCommon.HexToAddress("0xCfAA413eEb796f328620a3630Ae39124cabcEa92")
70 addrForge2 := ethCommon.HexToAddress("0x1fCb4ac309428feCc61B1C8cA5823C15A5e1a800")
71
72 var timer timer
73 clientSetup := NewClientSetupExample()
74 clientSetup.AuctionVariables.ClosedAuctionSlots = 2
75 clientSetup.AuctionVariables.OpenAuctionSlots = 100
76 c := NewClient(true, &timer, addrWithdraw, clientSetup)
77
78 _, err := c.AuctionBid(0, big.NewInt(1), addrForge)
79 assert.Equal(t, errBidClosed, err)
80
81 _, err = c.AuctionBid(102, big.NewInt(1), addrForge)
82 assert.Equal(t, errBidNotOpen, err)
83
84 _, err = c.AuctionBid(101, big.NewInt(16), addrForge)
85 assert.Equal(t, errCoordNotReg, err)
86
87 _, err = c.AuctionRegisterCoordinator(addrForge, "https://foo.bar")
88 assert.Nil(t, err)
89
90 _, err = c.AuctionBid(3, big.NewInt(1), addrForge)
91 assert.Equal(t, errBidBelowMin, err)
92
93 _, err = c.AuctionBid(3, big.NewInt(16), addrForge)
94 assert.Nil(t, err)
95
96 _, err = c.AuctionRegisterCoordinator(addrForge2, "https://foo2.bar")
97 assert.Nil(t, err)
98
99 _, err = c.AuctionBid(3, big.NewInt(16), addrForge2)
100 assert.Equal(t, errBidBelowMin, err)
101
102 _, err = c.AuctionBid(3, big.NewInt(17), addrForge2)
103 assert.Nil(t, err)
104
105 c.CtlMineBlock()
106
107 blockNum, err := c.EthCurrentBlock()
108 require.Nil(t, err)
109
110 auctionEvents, _, err := c.AuctionEventsByBlock(blockNum)
111 require.Nil(t, err)
112 assert.Equal(t, 2, len(auctionEvents.NewBid))
113}
114
115func TestClientRollup(t *testing.T) {
116 token1Addr := ethCommon.HexToAddress("0x6b175474e89094c44da98b954eedeac495271d0f")
117
118 var timer timer
119 clientSetup := NewClientSetupExample()
120 c := NewClient(true, &timer, ethCommon.Address{}, clientSetup)
121
122 // Add a token
123
124 tx, err := c.RollupAddToken(token1Addr)
125 require.Nil(t, err)
126 assert.NotNil(t, tx)
127
128 // Add some L1UserTxs
129 // Create Accounts
130
131 const N = 16
132 var keys [N]*keys
133 for i := 0; i < N; i++ {
134 keys[i] = genKeys(int64(i))
135 l1UserTx := common.L1Tx{
136 FromIdx: common.Idx(0),
137 FromEthAddr: keys[i].Addr,
138 FromBJJ: keys[i].BJJPublicKey,
139 TokenID: common.TokenID(0),
140 LoadAmount: big.NewInt(10 + int64(i)),
141 }
142 c.CtlAddL1TxUser(&l1UserTx)
143 }
144 c.CtlMineBlock()
145
146 blockNum, err := c.EthCurrentBlock()
147 require.Nil(t, err)
148 rollupEvents, _, err := c.RollupEventsByBlock(blockNum)
149 require.Nil(t, err)
150 assert.Equal(t, N, len(rollupEvents.L1UserTx))
151 assert.Equal(t, 1, len(rollupEvents.AddToken))
152
153 // Forge a batch
154
155 c.CtlAddBatch(ð.RollupForgeBatchArgs{
156 NewLastIdx: 0,
157 NewStRoot: big.NewInt(1),
158 NewExitRoot: big.NewInt(100),
159 L1CoordinatorTxs: []*common.L1Tx{},
160 L2Txs: []*common.L2Tx{},
161 FeeIdxCoordinator: make([]common.Idx, eth.FeeIdxCoordinatorLen),
162 VerifierIdx: 0,
163 L1Batch: true,
164 })
165 c.CtlMineBlock()
166
167 blockNumA, err := c.EthCurrentBlock()
168 require.Nil(t, err)
169 rollupEvents, hashA, err := c.RollupEventsByBlock(blockNumA)
170 require.Nil(t, err)
171 assert.Equal(t, 0, len(rollupEvents.L1UserTx))
172 assert.Equal(t, 0, len(rollupEvents.AddToken))
173 assert.Equal(t, 1, len(rollupEvents.ForgeBatch))
174
175 // Simulate reorg discarding last mined block
176
177 c.CtlRollback()
178 c.CtlMineBlock()
179
180 blockNumB, err := c.EthCurrentBlock()
181 require.Nil(t, err)
182 rollupEvents, hashB, err := c.RollupEventsByBlock(blockNumA)
183 require.Nil(t, err)
184 assert.Equal(t, 0, len(rollupEvents.L1UserTx))
185 assert.Equal(t, 0, len(rollupEvents.AddToken))
186 assert.Equal(t, 0, len(rollupEvents.ForgeBatch))
187
188 assert.Equal(t, blockNumA, blockNumB)
189 assert.NotEqual(t, hashA, hashB)
190
191 // Forge again
192 rollupForgeBatchArgs0 := ð.RollupForgeBatchArgs{
193 NewLastIdx: 0,
194 NewStRoot: big.NewInt(1),
195 NewExitRoot: big.NewInt(100),
196 L1CoordinatorTxs: []*common.L1Tx{},
197 L2Txs: []*common.L2Tx{},
198 FeeIdxCoordinator: make([]common.Idx, eth.FeeIdxCoordinatorLen),
199 VerifierIdx: 0,
200 L1Batch: true,
201 }
202 c.CtlAddBatch(rollupForgeBatchArgs0)
203 c.CtlMineBlock()
204
205 // Retrieve ForgeBatchArguments starting from the events
206
207 blockNum, err = c.EthCurrentBlock()
208 require.Nil(t, err)
209 rollupEvents, _, err = c.RollupEventsByBlock(blockNum)
210 require.Nil(t, err)
211
212 rollupForgeBatchArgs1, err := c.RollupForgeBatchArgs(rollupEvents.ForgeBatch[0].EthTxHash)
213 require.Nil(t, err)
214 assert.Equal(t, rollupForgeBatchArgs0, rollupForgeBatchArgs1)
215}
216
217type keys struct {
218 BJJSecretKey *babyjub.PrivateKey
219 BJJPublicKey *babyjub.PublicKey
220 Addr ethCommon.Address
221}
222
223func genKeys(i int64) *keys {
224 i++ // i = 0 doesn't work for the ecdsa key generation
225 var sk babyjub.PrivateKey
226 binary.LittleEndian.PutUint64(sk[:], uint64(i))
227
228 // eth address
229 var key ecdsa.PrivateKey
230 key.D = big.NewInt(i) // only for testing
231 key.PublicKey.X, key.PublicKey.Y = ethCrypto.S256().ScalarBaseMult(key.D.Bytes())
232 key.Curve = ethCrypto.S256()
233 addr := ethCrypto.PubkeyToAddress(key.PublicKey)
234
235 return &keys{
236 BJJSecretKey: &sk,
237 BJJPublicKey: sk.Public(),
238 Addr: addr,
239 }
240}