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.

417 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)
  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 batches[i%len(batches)].ForgeL1TxsNum != nil {
  138. // Add already forged txs
  139. tx.BatchNum = &batches[i%len(batches)].BatchNum
  140. setFromToAndAppend(fromIdx, tx, i, nUserTxs, userAddr, accounts, &userTxs, &othersTxs)
  141. } else {
  142. // Add unforged txs
  143. n := nextTxsNum
  144. tx.ToForgeL1TxsNum = &n
  145. tx.UserOrigin = true
  146. setFromToAndAppend(fromIdx, tx, i, nUserTxs, userAddr, accounts, &userTxs, &othersTxs)
  147. }
  148. }
  149. return userTxs, othersTxs
  150. }
  151. // GetNextToForgeNumAndBatch returns the next BatchNum and ForgeL1TxsNum to be added
  152. func GetNextToForgeNumAndBatch(batches []common.Batch) (common.BatchNum, int64) {
  153. batchNum := batches[len(batches)-1].BatchNum + 1
  154. var toForgeL1TxsNum int64
  155. found := false
  156. for i := len(batches) - 1; i >= 0; i-- {
  157. if batches[i].ForgeL1TxsNum != nil {
  158. toForgeL1TxsNum = *batches[i].ForgeL1TxsNum + 1
  159. found = true
  160. break
  161. }
  162. }
  163. if !found {
  164. panic("toForgeL1TxsNum not found")
  165. }
  166. return batchNum, toForgeL1TxsNum
  167. }
  168. func setFromToAndAppend(
  169. fromIdx int,
  170. tx common.L1Tx,
  171. i, nUserTxs int,
  172. userAddr *ethCommon.Address,
  173. accounts []common.Account,
  174. userTxs *[]common.L1Tx,
  175. othersTxs *[]common.L1Tx,
  176. ) {
  177. if i < fromIdx+nUserTxs {
  178. var from, to *common.Account
  179. var err error
  180. if i%2 == 0 {
  181. from, err = randomAccount(i, true, userAddr, accounts)
  182. if err != nil {
  183. panic(err)
  184. }
  185. to, err = randomAccount(i, false, userAddr, accounts)
  186. if err != nil {
  187. panic(err)
  188. }
  189. } else {
  190. from, err = randomAccount(i, false, userAddr, accounts)
  191. if err != nil {
  192. panic(err)
  193. }
  194. to, err = randomAccount(i, true, userAddr, accounts)
  195. if err != nil {
  196. panic(err)
  197. }
  198. }
  199. tx.FromIdx = from.Idx
  200. tx.FromEthAddr = from.EthAddr
  201. tx.FromBJJ = from.PublicKey
  202. tx.ToIdx = to.Idx
  203. *userTxs = append(*userTxs, tx)
  204. } else {
  205. from, err := randomAccount(i, false, userAddr, accounts)
  206. if err != nil {
  207. panic(err)
  208. }
  209. to, err := randomAccount(i, false, userAddr, accounts)
  210. if err != nil {
  211. panic(err)
  212. }
  213. tx.FromIdx = from.Idx
  214. tx.FromEthAddr = from.EthAddr
  215. tx.FromBJJ = from.PublicKey
  216. tx.ToIdx = to.Idx
  217. *othersTxs = append(*othersTxs, tx)
  218. }
  219. }
  220. // GenL2Txs generates L2 txs. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
  221. func GenL2Txs(
  222. fromIdx int,
  223. totalTxs, nUserTxs int,
  224. userAddr *ethCommon.Address,
  225. accounts []common.Account,
  226. tokens []common.Token,
  227. blocks []common.Block,
  228. batches []common.Batch,
  229. ) ([]common.L2Tx, []common.L2Tx) {
  230. if totalTxs < nUserTxs {
  231. panic("totalTxs must be greater than userTxs")
  232. }
  233. userTxs := []common.L2Tx{}
  234. othersTxs := []common.L2Tx{}
  235. for i := fromIdx; i < fromIdx+totalTxs; i++ {
  236. amount := big.NewInt(int64(i + 1))
  237. fee := common.FeeSelector(i % 256) //nolint:gomnd
  238. tx := common.L2Tx{
  239. TxID: common.TxID([12]byte{2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, byte(i)}), // only for testing purposes
  240. BatchNum: batches[i%len(batches)].BatchNum,
  241. Position: i - fromIdx,
  242. Amount: amount,
  243. Fee: fee,
  244. Nonce: common.Nonce(i + 1),
  245. EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
  246. Type: randomTxType(i),
  247. }
  248. if i < nUserTxs {
  249. var from, to *common.Account
  250. var err error
  251. if i%2 == 0 {
  252. from, err = randomAccount(i, true, userAddr, accounts)
  253. if err != nil {
  254. panic(err)
  255. }
  256. to, err = randomAccount(i, false, userAddr, accounts)
  257. if err != nil {
  258. panic(err)
  259. }
  260. } else {
  261. from, err = randomAccount(i, false, userAddr, accounts)
  262. if err != nil {
  263. panic(err)
  264. }
  265. to, err = randomAccount(i, true, userAddr, accounts)
  266. if err != nil {
  267. panic(err)
  268. }
  269. }
  270. tx.FromIdx = from.Idx
  271. tx.ToIdx = to.Idx
  272. } else {
  273. from, err := randomAccount(i, false, userAddr, accounts)
  274. if err != nil {
  275. panic(err)
  276. }
  277. to, err := randomAccount(i, false, userAddr, accounts)
  278. if err != nil {
  279. panic(err)
  280. }
  281. tx.FromIdx = from.Idx
  282. tx.ToIdx = to.Idx
  283. }
  284. if i < nUserTxs {
  285. userTxs = append(userTxs, tx)
  286. } else {
  287. othersTxs = append(othersTxs, tx)
  288. }
  289. }
  290. return userTxs, othersTxs
  291. }
  292. // GenCoordinators generates coordinators. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
  293. func GenCoordinators(nCoords int, blocks []common.Block) []common.Coordinator {
  294. coords := []common.Coordinator{}
  295. for i := 0; i < nCoords; i++ {
  296. coords = append(coords, common.Coordinator{
  297. EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
  298. Forger: ethCommon.BigToAddress(big.NewInt(int64(i))),
  299. Bidder: ethCommon.BigToAddress(big.NewInt(int64(i))),
  300. URL: "https://foo.bar",
  301. })
  302. }
  303. return coords
  304. }
  305. // GenBids generates bids. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
  306. func GenBids(nBids int, blocks []common.Block, coords []common.Coordinator) []common.Bid {
  307. bids := []common.Bid{}
  308. for i := 0; i < nBids; i++ {
  309. bids = append(bids, common.Bid{
  310. SlotNum: common.SlotNum(i),
  311. BidValue: big.NewInt(int64(i)),
  312. EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
  313. Bidder: coords[i%len(blocks)].Bidder,
  314. })
  315. }
  316. return bids
  317. }
  318. // GenExitTree generates an exitTree (as an array of Exits)
  319. //nolint:gomnd
  320. func GenExitTree(n int) []common.ExitInfo {
  321. exitTree := make([]common.ExitInfo, n)
  322. for i := 0; i < n; i++ {
  323. exitTree[i] = common.ExitInfo{
  324. BatchNum: common.BatchNum(i + 1),
  325. InstantWithdrawn: nil,
  326. DelayedWithdrawRequest: nil,
  327. DelayedWithdrawn: nil,
  328. AccountIdx: common.Idx(i * 10),
  329. MerkleProof: &merkletree.CircomVerifierProof{
  330. Root: &merkletree.Hash{byte(i), byte(i + 1)},
  331. Siblings: []*big.Int{
  332. big.NewInt(int64(i) * 10),
  333. big.NewInt(int64(i)*100 + 1),
  334. big.NewInt(int64(i)*1000 + 2)},
  335. OldKey: &merkletree.Hash{byte(i * 1), byte(i*1 + 1)},
  336. OldValue: &merkletree.Hash{byte(i * 2), byte(i*2 + 1)},
  337. IsOld0: i%2 == 0,
  338. Key: &merkletree.Hash{byte(i * 3), byte(i*3 + 1)},
  339. Value: &merkletree.Hash{byte(i * 4), byte(i*4 + 1)},
  340. Fnc: i % 2,
  341. },
  342. Balance: big.NewInt(int64(i) * 1000),
  343. }
  344. }
  345. return exitTree
  346. }
  347. func randomAccount(seed int, userAccount bool, userAddr *ethCommon.Address, accs []common.Account) (*common.Account, error) {
  348. i := seed % len(accs)
  349. firstI := i
  350. for {
  351. acc := accs[i]
  352. if userAccount && *userAddr == acc.EthAddr {
  353. return &acc, nil
  354. }
  355. if !userAccount && (userAddr == nil || *userAddr != acc.EthAddr) {
  356. return &acc, nil
  357. }
  358. i++
  359. i = i % len(accs)
  360. if i == firstI {
  361. return &acc, errors.New("Didnt found any account matchinng the criteria")
  362. }
  363. }
  364. }
  365. func randomTxType(seed int) common.TxType {
  366. //nolint:gomnd
  367. switch seed % 11 {
  368. case 0:
  369. return common.TxTypeExit
  370. //nolint:gomnd
  371. case 2:
  372. return common.TxTypeTransfer
  373. //nolint:gomnd
  374. case 3:
  375. return common.TxTypeDeposit
  376. //nolint:gomnd
  377. case 4:
  378. return common.TxTypeCreateAccountDeposit
  379. //nolint:gomnd
  380. case 5:
  381. return common.TxTypeCreateAccountDepositTransfer
  382. //nolint:gomnd
  383. case 6:
  384. return common.TxTypeDepositTransfer
  385. //nolint:gomnd
  386. case 7:
  387. return common.TxTypeForceTransfer
  388. //nolint:gomnd
  389. case 8:
  390. return common.TxTypeForceExit
  391. //nolint:gomnd
  392. case 9:
  393. return common.TxTypeTransferToEthAddr
  394. //nolint:gomnd
  395. case 10:
  396. return common.TxTypeTransferToBJJ
  397. default:
  398. return common.TxTypeTransfer
  399. }
  400. }