hermez-node/test/historydb.go
test/historydb.goRaw
1package test
2
3import (
4 "errors"
5 "fmt"
6 "math/big"
7 "strconv"
8 "time"
9
10 ethCommon "github.com/ethereum/go-ethereum/common"
11 "github.com/hermeznetwork/hermez-node/common"
12 "github.com/iden3/go-iden3-crypto/babyjub"
13)
14
15// WARNING: the generators in this file doesn't necessary follow the protocol
16// they are intended to check that the parsers between struct <==> DB are correct
17
18// GenBlocks generates block from, to block numbers. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
19func GenBlocks(from, to int64) []common.Block {
20 var blocks []common.Block
21 for i := from; i < to; i++ {
22 blocks = append(blocks, common.Block{
23 EthBlockNum: i,
24 //nolint:gomnd
25 Timestamp: time.Now().Add(time.Second * 13).UTC(),
26 Hash: ethCommon.BigToHash(big.NewInt(int64(i))),
27 })
28 }
29 return blocks
30}
31
32// GenTokens generates tokens. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
33func GenTokens(nTokens int, blocks []common.Block) []common.Token {
34 tokens := []common.Token{}
35 for i := 0; i < nTokens; i++ {
36 token := common.Token{
37 TokenID: common.TokenID(i),
38 Name: fmt.Sprint(i),
39 Symbol: fmt.Sprint(i),
40 Decimals: uint64(i),
41 EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
42 EthAddr: ethCommon.BigToAddress(big.NewInt(int64(i))),
43 }
44 if i%2 == 0 {
45 token.USD = 3
46 token.USDUpdate = time.Now()
47 }
48 tokens = append(tokens, token)
49 }
50 return tokens
51}
52
53// GenBatches generates batches. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
54func GenBatches(nBatches int, blocks []common.Block) []common.Batch {
55 batches := []common.Batch{}
56 collectedFees := make(map[common.TokenID]*big.Int)
57 for i := 0; i < 64; i++ {
58 collectedFees[common.TokenID(i)] = big.NewInt(int64(i))
59 }
60 for i := 0; i < nBatches; i++ {
61 batch := common.Batch{
62 BatchNum: common.BatchNum(i + 1),
63 EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
64 //nolint:gomnd
65 ForgerAddr: ethCommon.BigToAddress(big.NewInt(6886723)),
66 CollectedFees: collectedFees,
67 StateRoot: common.Hash([]byte("duhdqlwiucgwqeiu")),
68 //nolint:gomnd
69 NumAccounts: 30,
70 ExitRoot: common.Hash([]byte("tykertheuhtgenuer3iuw3b")),
71 SlotNum: common.SlotNum(i),
72 }
73 if i%2 == 0 {
74 batch.ForgeL1TxsNum = int64(i)
75 }
76 batches = append(batches, batch)
77 }
78 return batches
79}
80
81// GenAccounts generates accounts. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
82func GenAccounts(totalAccounts, userAccounts int, tokens []common.Token, userAddr *ethCommon.Address, userBjj *babyjub.PublicKey, batches []common.Batch) []common.Account {
83 if totalAccounts < userAccounts {
84 panic("totalAccounts must be greater than userAccounts")
85 }
86 accs := []common.Account{}
87 for i := 0; i < totalAccounts; i++ {
88 var addr ethCommon.Address
89 var pubK *babyjub.PublicKey
90 if i < userAccounts {
91 addr = *userAddr
92 pubK = userBjj
93 } else {
94 addr = ethCommon.BigToAddress(big.NewInt(int64(i)))
95 privK := babyjub.NewRandPrivKey()
96 pubK = privK.Public()
97 }
98 accs = append(accs, common.Account{
99 Idx: common.Idx(i),
100 TokenID: tokens[i%len(tokens)].TokenID,
101 EthAddr: addr,
102 BatchNum: batches[i%len(batches)].BatchNum,
103 PublicKey: pubK,
104 })
105 }
106 return accs
107}
108
109// GenL1Txs generates L1 txs. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
110func GenL1Txs(
111 fromIdx int,
112 totalTxs, nUserTxs int,
113 userAddr *ethCommon.Address,
114 accounts []common.Account,
115 tokens []common.Token,
116 blocks []common.Block,
117 batches []common.Batch,
118) ([]common.L1Tx, []common.L1Tx) {
119 if totalTxs < nUserTxs {
120 panic("totalTxs must be greater than userTxs")
121 }
122 userTxs := []common.L1Tx{}
123 othersTxs := []common.L1Tx{}
124 for i := 0; i < totalTxs; i++ {
125 var tx common.L1Tx
126 if batches[i%len(batches)].ForgeL1TxsNum != 0 {
127 tx = common.L1Tx{
128 TxID: common.TxID(common.Hash([]byte("L1_" + strconv.Itoa(fromIdx+i)))),
129 ToForgeL1TxsNum: batches[i%len(batches)].ForgeL1TxsNum,
130 Position: i,
131 UserOrigin: i%2 == 0,
132 TokenID: tokens[i%len(tokens)].TokenID,
133 Amount: big.NewInt(int64(i + 1)),
134 LoadAmount: big.NewInt(int64(i + 1)),
135 EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
136 Type: randomTxType(i),
137 }
138 if i%4 == 0 {
139 tx.BatchNum = batches[i%len(batches)].BatchNum
140 }
141 } else {
142 continue
143 }
144 if i < nUserTxs {
145 var from, to common.Account
146 var err error
147 if i%2 == 0 {
148 from, err = randomAccount(i, true, userAddr, accounts)
149 if err != nil {
150 panic(err)
151 }
152 to, err = randomAccount(i, false, userAddr, accounts)
153 if err != nil {
154 panic(err)
155 }
156 } else {
157 from, err = randomAccount(i, false, userAddr, accounts)
158 if err != nil {
159 panic(err)
160 }
161 to, err = randomAccount(i, true, userAddr, accounts)
162 if err != nil {
163 panic(err)
164 }
165 }
166 tx.FromIdx = from.Idx
167 tx.FromEthAddr = from.EthAddr
168 tx.FromBJJ = from.PublicKey
169 tx.ToIdx = to.Idx
170 userTxs = append(userTxs, tx)
171 } else {
172 from, err := randomAccount(i, false, userAddr, accounts)
173 if err != nil {
174 panic(err)
175 }
176 to, err := randomAccount(i, false, userAddr, accounts)
177 if err != nil {
178 panic(err)
179 }
180 tx.FromIdx = from.Idx
181 tx.FromEthAddr = from.EthAddr
182 tx.FromBJJ = from.PublicKey
183 tx.ToIdx = to.Idx
184 othersTxs = append(othersTxs, tx)
185 }
186 }
187 return userTxs, othersTxs
188}
189
190// GenL2Txs generates L2 txs. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
191func GenL2Txs(
192 fromIdx int,
193 totalTxs, nUserTxs int,
194 userAddr *ethCommon.Address,
195 accounts []common.Account,
196 tokens []common.Token,
197 blocks []common.Block,
198 batches []common.Batch,
199) ([]common.L2Tx, []common.L2Tx) {
200 if totalTxs < nUserTxs {
201 panic("totalTxs must be greater than userTxs")
202 }
203 userTxs := []common.L2Tx{}
204 othersTxs := []common.L2Tx{}
205 for i := 0; i < totalTxs; i++ {
206 tx := common.L2Tx{
207 TxID: common.TxID(common.Hash([]byte("L2_" + strconv.Itoa(fromIdx+i)))),
208 BatchNum: batches[i%len(batches)].BatchNum,
209 Position: i,
210 //nolint:gomnd
211 Amount: big.NewInt(int64(i + 1)),
212 //nolint:gomnd
213 Fee: common.FeeSelector(i % 256),
214 Nonce: common.Nonce(i + 1),
215 EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
216 Type: randomTxType(i),
217 }
218 if i < nUserTxs {
219 var from, to common.Account
220 var err error
221 if i%2 == 0 {
222 from, err = randomAccount(i, true, userAddr, accounts)
223 if err != nil {
224 panic(err)
225 }
226 to, err = randomAccount(i, false, userAddr, accounts)
227 if err != nil {
228 panic(err)
229 }
230 } else {
231 from, err = randomAccount(i, false, userAddr, accounts)
232 if err != nil {
233 panic(err)
234 }
235 to, err = randomAccount(i, true, userAddr, accounts)
236 if err != nil {
237 panic(err)
238 }
239 }
240 tx.FromIdx = from.Idx
241 tx.ToIdx = to.Idx
242 userTxs = append(userTxs, tx)
243 } else {
244 from, err := randomAccount(i, false, userAddr, accounts)
245 if err != nil {
246 panic(err)
247 }
248 to, err := randomAccount(i, false, userAddr, accounts)
249 if err != nil {
250 panic(err)
251 }
252 tx.FromIdx = from.Idx
253 tx.ToIdx = to.Idx
254 othersTxs = append(othersTxs, tx)
255 }
256 }
257 return userTxs, othersTxs
258}
259
260// GenCoordinators generates coordinators. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
261func GenCoordinators(nCoords int, blocks []common.Block) []common.Coordinator {
262 coords := []common.Coordinator{}
263 for i := 0; i < nCoords; i++ {
264 coords = append(coords, common.Coordinator{
265 EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
266 Forger: ethCommon.BigToAddress(big.NewInt(int64(i))),
267 Withdraw: ethCommon.BigToAddress(big.NewInt(int64(i))),
268 URL: "https://foo.bar",
269 })
270 }
271 return coords
272}
273
274// GenBids generates bids. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
275func GenBids(nBids int, blocks []common.Block, coords []common.Coordinator) []common.Bid {
276 bids := []common.Bid{}
277 for i := 0; i < nBids; i++ {
278 bids = append(bids, common.Bid{
279 SlotNum: common.SlotNum(i),
280 BidValue: big.NewInt(int64(i)),
281 EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
282 ForgerAddr: coords[i%len(blocks)].Forger,
283 })
284 }
285 return bids
286}
287
288func randomAccount(seed int, userAccount bool, userAddr *ethCommon.Address, accs []common.Account) (common.Account, error) {
289 i := seed % len(accs)
290 firstI := i
291 for {
292 acc := accs[i]
293 if userAccount && *userAddr == acc.EthAddr {
294 return acc, nil
295 }
296 if !userAccount && (userAddr == nil || *userAddr != acc.EthAddr) {
297 return acc, nil
298 }
299 i++
300 i = i % len(accs)
301 if i == firstI {
302 return acc, errors.New("Didnt found any account matchinng the criteria")
303 }
304 }
305}
306
307func randomTxType(seed int) common.TxType {
308 //nolint:gomnd
309 switch seed % 11 {
310 case 0:
311 return common.TxTypeExit
312 //nolint:gomnd
313 case 1:
314 return common.TxTypeWithdrawn
315 //nolint:gomnd
316 case 2:
317 return common.TxTypeTransfer
318 //nolint:gomnd
319 case 3:
320 return common.TxTypeDeposit
321 //nolint:gomnd
322 case 4:
323 return common.TxTypeCreateAccountDeposit
324 //nolint:gomnd
325 case 5:
326 return common.TxTypeCreateAccountDepositTransfer
327 //nolint:gomnd
328 case 6:
329 return common.TxTypeDepositTransfer
330 //nolint:gomnd
331 case 7:
332 return common.TxTypeForceTransfer
333 //nolint:gomnd
334 case 8:
335 return common.TxTypeForceExit
336 //nolint:gomnd
337 case 9:
338 return common.TxTypeTransferToEthAddr
339 //nolint:gomnd
340 case 10:
341 return common.TxTypeTransferToBJJ
342 default:
343 return common.TxTypeTransfer
344 }
345}