arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
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}