You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

433 lines
12 KiB

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