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 = uint32(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, batches []common.Batch) []common.Account {
83 if totalAccounts < userAccounts {
84 panic("totalAccounts must be greater than userAccounts")
85 }
86 privK := babyjub.NewRandPrivKey()
87 pubK := privK.Public()
88 accs := []common.Account{}
89 for i := 0; i < totalAccounts; i++ {
90 var addr ethCommon.Address
91 if i < userAccounts {
92 addr = *userAddr
93 } else {
94 addr = ethCommon.BigToAddress(big.NewInt(int64(i)))
95 }
96 accs = append(accs, common.Account{
97 Idx: common.Idx(i),
98 TokenID: tokens[i%len(tokens)].TokenID,
99 EthAddr: addr,
100 BatchNum: batches[i%len(batches)].BatchNum,
101 PublicKey: pubK,
102 })
103 }
104 return accs
105}
106
107// GenL1Txs generates L1 txs. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
108func GenL1Txs(
109 fromIdx int,
110 totalTxs, nUserTxs int,
111 userAddr *ethCommon.Address,
112 accounts []common.Account,
113 tokens []common.Token,
114 blocks []common.Block,
115 batches []common.Batch,
116) ([]common.L1Tx, []common.L1Tx) {
117 if totalTxs < nUserTxs {
118 panic("totalTxs must be greater than userTxs")
119 }
120 userTxs := []common.L1Tx{}
121 othersTxs := []common.L1Tx{}
122 for i := 0; i < totalTxs; i++ {
123 var tx common.L1Tx
124 if batches[i%len(batches)].ForgeL1TxsNum != 0 {
125 tx = common.L1Tx{
126 TxID: common.TxID(common.Hash([]byte("L1_" + strconv.Itoa(fromIdx+i)))),
127 ToForgeL1TxsNum: batches[i%len(batches)].ForgeL1TxsNum,
128 Position: i,
129 UserOrigin: i%2 == 0,
130 TokenID: tokens[i%len(tokens)].TokenID,
131 Amount: big.NewInt(int64(i + 1)),
132 LoadAmount: big.NewInt(int64(i + 1)),
133 EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
134 Type: randomTxType(i),
135 }
136 if i%4 == 0 {
137 tx.BatchNum = batches[i%len(batches)].BatchNum
138 }
139 } else {
140 continue
141 }
142 if i < nUserTxs {
143 var from, to common.Account
144 var err error
145 if i%2 == 0 {
146 from, err = randomAccount(i, true, userAddr, accounts)
147 if err != nil {
148 panic(err)
149 }
150 to, err = randomAccount(i, false, userAddr, accounts)
151 if err != nil {
152 panic(err)
153 }
154 } else {
155 from, err = randomAccount(i, false, userAddr, accounts)
156 if err != nil {
157 panic(err)
158 }
159 to, err = randomAccount(i, true, userAddr, accounts)
160 if err != nil {
161 panic(err)
162 }
163 }
164 tx.FromIdx = from.Idx
165 tx.FromEthAddr = from.EthAddr
166 tx.FromBJJ = from.PublicKey
167 tx.ToIdx = to.Idx
168 userTxs = append(userTxs, tx)
169 } else {
170 from, err := randomAccount(i, false, userAddr, accounts)
171 if err != nil {
172 panic(err)
173 }
174 to, err := randomAccount(i, false, userAddr, accounts)
175 if err != nil {
176 panic(err)
177 }
178 tx.FromIdx = from.Idx
179 tx.FromEthAddr = from.EthAddr
180 tx.FromBJJ = from.PublicKey
181 tx.ToIdx = to.Idx
182 othersTxs = append(othersTxs, tx)
183 }
184 }
185 return userTxs, othersTxs
186}
187
188// GenL2Txs generates L2 txs. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
189func GenL2Txs(
190 fromIdx int,
191 totalTxs, nUserTxs int,
192 userAddr *ethCommon.Address,
193 accounts []common.Account,
194 tokens []common.Token,
195 blocks []common.Block,
196 batches []common.Batch,
197) ([]common.L2Tx, []common.L2Tx) {
198 if totalTxs < nUserTxs {
199 panic("totalTxs must be greater than userTxs")
200 }
201 userTxs := []common.L2Tx{}
202 othersTxs := []common.L2Tx{}
203 for i := 0; i < totalTxs; i++ {
204 tx := common.L2Tx{
205 TxID: common.TxID(common.Hash([]byte("L2_" + strconv.Itoa(fromIdx+i)))),
206 BatchNum: batches[i%len(batches)].BatchNum,
207 Position: i,
208 //nolint:gomnd
209 Amount: big.NewInt(int64(i + 1)),
210 //nolint:gomnd
211 Fee: common.FeeSelector(i % 256),
212 Nonce: common.Nonce(i + 1),
213 EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
214 Type: randomTxType(i),
215 }
216 if i < nUserTxs {
217 var from, to common.Account
218 var err error
219 if i%2 == 0 {
220 from, err = randomAccount(i, true, userAddr, accounts)
221 if err != nil {
222 panic(err)
223 }
224 to, err = randomAccount(i, false, userAddr, accounts)
225 if err != nil {
226 panic(err)
227 }
228 } else {
229 from, err = randomAccount(i, false, userAddr, accounts)
230 if err != nil {
231 panic(err)
232 }
233 to, err = randomAccount(i, true, userAddr, accounts)
234 if err != nil {
235 panic(err)
236 }
237 }
238 tx.FromIdx = from.Idx
239 tx.ToIdx = to.Idx
240 userTxs = append(userTxs, tx)
241 } else {
242 from, err := randomAccount(i, false, userAddr, accounts)
243 if err != nil {
244 panic(err)
245 }
246 to, err := randomAccount(i, false, userAddr, accounts)
247 if err != nil {
248 panic(err)
249 }
250 tx.FromIdx = from.Idx
251 tx.ToIdx = to.Idx
252 othersTxs = append(othersTxs, tx)
253 }
254 }
255 return userTxs, othersTxs
256}
257
258// GenCoordinators generates coordinators. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
259func GenCoordinators(nCoords int, blocks []common.Block) []common.Coordinator {
260 coords := []common.Coordinator{}
261 for i := 0; i < nCoords; i++ {
262 coords = append(coords, common.Coordinator{
263 EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
264 Forger: ethCommon.BigToAddress(big.NewInt(int64(i))),
265 Withdraw: ethCommon.BigToAddress(big.NewInt(int64(i))),
266 URL: "https://foo.bar",
267 })
268 }
269 return coords
270}
271
272// GenBids generates bids. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
273func GenBids(nBids int, blocks []common.Block, coords []common.Coordinator) []common.Bid {
274 bids := []common.Bid{}
275 for i := 0; i < nBids; i++ {
276 bids = append(bids, common.Bid{
277 SlotNum: common.SlotNum(i),
278 BidValue: big.NewInt(int64(i)),
279 EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
280 ForgerAddr: coords[i%len(blocks)].Forger,
281 })
282 }
283 return bids
284}
285
286func randomAccount(seed int, userAccount bool, userAddr *ethCommon.Address, accs []common.Account) (common.Account, error) {
287 i := seed % len(accs)
288 firstI := i
289 for {
290 acc := accs[i]
291 if userAccount && *userAddr == acc.EthAddr {
292 return acc, nil
293 }
294 if !userAccount && (userAddr == nil || *userAddr != acc.EthAddr) {
295 return acc, nil
296 }
297 i++
298 i = i % len(accs)
299 if i == firstI {
300 return acc, errors.New("Didnt found any account matchinng the criteria")
301 }
302 }
303}
304
305func randomTxType(seed int) common.TxType {
306 //nolint:gomnd
307 switch seed % 11 {
308 case 0:
309 return common.TxTypeExit
310 //nolint:gomnd
311 case 1:
312 return common.TxTypeWithdrawn
313 //nolint:gomnd
314 case 2:
315 return common.TxTypeTransfer
316 //nolint:gomnd
317 case 3:
318 return common.TxTypeDeposit
319 //nolint:gomnd
320 case 4:
321 return common.TxTypeCreateAccountDeposit
322 //nolint:gomnd
323 case 5:
324 return common.TxTypeCreateAccountDepositTransfer
325 //nolint:gomnd
326 case 6:
327 return common.TxTypeDepositTransfer
328 //nolint:gomnd
329 case 7:
330 return common.TxTypeForceTransfer
331 //nolint:gomnd
332 case 8:
333 return common.TxTypeForceExit
334 //nolint:gomnd
335 case 9:
336 return common.TxTypeTransferToEthAddr
337 //nolint:gomnd
338 case 10:
339 return common.TxTypeTransferToBJJ
340 default:
341 return common.TxTypeTransfer
342 }
343}