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 = 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}