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
20var clientSetup *ClientSetup
21
22func init() {
23 rollupConstants := ð.RollupConstants{}
24 rollupVariables := ð.RollupVariables{
25 MaxTxVerifiers: make([]int, 0),
26 TokenHEZ: ethCommon.Address{},
27 GovernanceAddress: ethCommon.Address{},
28 SafetyBot: ethCommon.Address{},
29 ConsensusContract: ethCommon.Address{},
30 WithdrawalContract: ethCommon.Address{},
31 FeeAddToken: big.NewInt(1),
32 ForgeL1Timeout: 16,
33 FeeL1UserTx: big.NewInt(2),
34 }
35 auctionConstants := ð.AuctionConstants{}
36 auctionVariables := ð.AuctionVariables{
37 DonationAddress: ethCommon.Address{},
38 BootCoordinator: ethCommon.Address{},
39 MinBidEpoch: [6]*big.Int{
40 big.NewInt(10), big.NewInt(11), big.NewInt(12),
41 big.NewInt(13), big.NewInt(14), big.NewInt(15)},
42 ClosedAuctionSlots: 0,
43 OpenAuctionSlots: 0,
44 AllocationRatio: [3]uint8{},
45 Outbidding: 0,
46 SlotDeadline: 0,
47 }
48 clientSetup = &ClientSetup{
49 RollupConstants: rollupConstants,
50 RollupVariables: rollupVariables,
51 AuctionConstants: auctionConstants,
52 AuctionVariables: auctionVariables,
53 }
54}
55
56type timer struct {
57 time int64
58}
59
60func (t *timer) Time() int64 {
61 currentTime := t.time
62 t.time++
63 return currentTime
64}
65
66func TestClientInterface(t *testing.T) {
67 var c eth.ClientInterface
68 var timer timer
69 client := NewClient(true, &timer, clientSetup)
70 c = client
71 require.NotNil(t, c)
72}
73
74func TestEthClient(t *testing.T) {
75 token1Addr := ethCommon.HexToAddress("0x6b175474e89094c44da98b954eedeac495271d0f")
76
77 var timer timer
78 c := NewClient(true, &timer, clientSetup)
79 blockNum, err := c.EthCurrentBlock()
80 require.Nil(t, err)
81 assert.Equal(t, int64(0), blockNum)
82
83 block, err := c.EthBlockByNumber(context.TODO(), 0)
84 require.Nil(t, err)
85 assert.Equal(t, int64(0), block.EthBlockNum)
86 assert.Equal(t, time.Unix(0, 0), block.Timestamp)
87 assert.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000000", block.Hash.Hex())
88 assert.Equal(t, int64(0), c.blockNum)
89
90 // Mine some empty blocks
91
92 c.CtlMineBlock()
93 assert.Equal(t, int64(1), c.blockNum)
94 c.CtlMineBlock()
95 assert.Equal(t, int64(2), c.blockNum)
96
97 block, err = c.EthBlockByNumber(context.TODO(), 2)
98 require.Nil(t, err)
99 assert.Equal(t, int64(2), block.EthBlockNum)
100 assert.Equal(t, time.Unix(2, 0), block.Timestamp)
101
102 // Add a token
103
104 tx, err := c.RollupAddToken(token1Addr)
105 require.Nil(t, err)
106 assert.NotNil(t, tx)
107
108 // Add some L1UserTxs
109 // Create Accounts
110
111 const N = 16
112 var keys [N]*keys
113 for i := 0; i < N; i++ {
114 keys[i] = genKeys(int64(i))
115 l1UserTx := common.L1Tx{
116 FromIdx: common.Idx(0),
117 FromEthAddr: keys[i].Addr,
118 FromBJJ: keys[i].BJJPublicKey,
119 TokenID: common.TokenID(0),
120 LoadAmount: big.NewInt(10 + int64(i)),
121 }
122 c.CtlAddL1TxUser(&l1UserTx)
123 }
124 c.CtlMineBlock()
125
126 blockNum, err = c.EthCurrentBlock()
127 require.Nil(t, err)
128 rollupEvents, _, err := c.RollupEventsByBlock(blockNum)
129 require.Nil(t, err)
130 assert.Equal(t, N, len(rollupEvents.L1UserTx))
131 assert.Equal(t, 1, len(rollupEvents.AddToken))
132
133 // Forge a batch
134
135 c.CtlAddBatch(ð.RollupForgeBatchArgs{
136 NewLastIdx: 0,
137 NewStRoot: big.NewInt(1),
138 NewExitRoot: big.NewInt(100),
139 L1CoordinatorTxs: []*common.L1Tx{},
140 L2Txs: []*common.L2Tx{},
141 FeeIdxCoordinator: make([]common.Idx, eth.FeeIdxCoordinatorLen),
142 VerifierIdx: 0,
143 L1Batch: true,
144 })
145 c.CtlMineBlock()
146
147 blockNumA, err := c.EthCurrentBlock()
148 require.Nil(t, err)
149 rollupEvents, hashA, err := c.RollupEventsByBlock(blockNumA)
150 require.Nil(t, err)
151 assert.Equal(t, 0, len(rollupEvents.L1UserTx))
152 assert.Equal(t, 0, len(rollupEvents.AddToken))
153 assert.Equal(t, 1, len(rollupEvents.ForgeBatch))
154
155 // Simulate reorg discarding last mined block
156
157 c.CtlRollback()
158 c.CtlMineBlock()
159
160 blockNumB, err := c.EthCurrentBlock()
161 require.Nil(t, err)
162 rollupEvents, hashB, err := c.RollupEventsByBlock(blockNumA)
163 require.Nil(t, err)
164 assert.Equal(t, 0, len(rollupEvents.L1UserTx))
165 assert.Equal(t, 0, len(rollupEvents.AddToken))
166 assert.Equal(t, 0, len(rollupEvents.ForgeBatch))
167
168 assert.Equal(t, blockNumA, blockNumB)
169 assert.NotEqual(t, hashA, hashB)
170
171 // Forge again
172 rollupForgeBatchArgs0 := ð.RollupForgeBatchArgs{
173 NewLastIdx: 0,
174 NewStRoot: big.NewInt(1),
175 NewExitRoot: big.NewInt(100),
176 L1CoordinatorTxs: []*common.L1Tx{},
177 L2Txs: []*common.L2Tx{},
178 FeeIdxCoordinator: make([]common.Idx, eth.FeeIdxCoordinatorLen),
179 VerifierIdx: 0,
180 L1Batch: true,
181 }
182 c.CtlAddBatch(rollupForgeBatchArgs0)
183 c.CtlMineBlock()
184
185 // Retrieve ForgeBatchArguments starting from the events
186
187 blockNum, err = c.EthCurrentBlock()
188 require.Nil(t, err)
189 rollupEvents, _, err = c.RollupEventsByBlock(blockNum)
190 require.Nil(t, err)
191
192 rollupForgeBatchArgs1, err := c.RollupForgeBatchArgs(rollupEvents.ForgeBatch[0].EthTxHash)
193 require.Nil(t, err)
194 assert.Equal(t, rollupForgeBatchArgs0, rollupForgeBatchArgs1)
195}
196
197type keys struct {
198 BJJSecretKey *babyjub.PrivateKey
199 BJJPublicKey *babyjub.PublicKey
200 Addr ethCommon.Address
201}
202
203func genKeys(i int64) *keys {
204 i++ // i = 0 doesn't work for the ecdsa key generation
205 var sk babyjub.PrivateKey
206 binary.LittleEndian.PutUint64(sk[:], uint64(i))
207
208 // eth address
209 var key ecdsa.PrivateKey
210 key.D = big.NewInt(i) // only for testing
211 key.PublicKey.X, key.PublicKey.Y = ethCrypto.S256().ScalarBaseMult(key.D.Bytes())
212 key.Curve = ethCrypto.S256()
213 addr := ethCrypto.PubkeyToAddress(key.PublicKey)
214
215 return &keys{
216 BJJSecretKey: &sk,
217 BJJPublicKey: sk.Public(),
218 Addr: addr,
219 }
220}