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.

343 lines
9.4 KiB

  1. package test
  2. import (
  3. "errors"
  4. "fmt"
  5. "math/big"
  6. "strconv"
  7. "time"
  8. ethCommon "github.com/ethereum/go-ethereum/common"
  9. "github.com/hermeznetwork/hermez-node/common"
  10. "github.com/iden3/go-iden3-crypto/babyjub"
  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. if i%2 == 0 {
  40. token.USD = 3
  41. token.USDUpdate = time.Now()
  42. }
  43. tokens = append(tokens, token)
  44. }
  45. return tokens
  46. }
  47. // GenBatches generates batches. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
  48. func GenBatches(nBatches int, blocks []common.Block) []common.Batch {
  49. batches := []common.Batch{}
  50. collectedFees := make(map[common.TokenID]*big.Int)
  51. for i := 0; i < 64; i++ {
  52. collectedFees[common.TokenID(i)] = big.NewInt(int64(i))
  53. }
  54. for i := 0; i < nBatches; i++ {
  55. batch := common.Batch{
  56. BatchNum: common.BatchNum(i + 1),
  57. EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
  58. //nolint:gomnd
  59. ForgerAddr: ethCommon.BigToAddress(big.NewInt(6886723)),
  60. CollectedFees: collectedFees,
  61. StateRoot: common.Hash([]byte("duhdqlwiucgwqeiu")),
  62. //nolint:gomnd
  63. NumAccounts: 30,
  64. ExitRoot: common.Hash([]byte("tykertheuhtgenuer3iuw3b")),
  65. SlotNum: common.SlotNum(i),
  66. }
  67. if i%2 == 0 {
  68. batch.ForgeL1TxsNum = int64(i)
  69. }
  70. batches = append(batches, batch)
  71. }
  72. return batches
  73. }
  74. // GenAccounts generates accounts. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
  75. func GenAccounts(totalAccounts, userAccounts int, tokens []common.Token, userAddr *ethCommon.Address, batches []common.Batch) []common.Account {
  76. if totalAccounts < userAccounts {
  77. panic("totalAccounts must be greater than userAccounts")
  78. }
  79. privK := babyjub.NewRandPrivKey()
  80. pubK := privK.Public()
  81. accs := []common.Account{}
  82. for i := 0; i < totalAccounts; i++ {
  83. var addr ethCommon.Address
  84. if i < userAccounts {
  85. addr = *userAddr
  86. } else {
  87. addr = ethCommon.BigToAddress(big.NewInt(int64(i)))
  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. for i := 0; i < totalTxs; i++ {
  115. var tx common.L1Tx
  116. if batches[i%len(batches)].ForgeL1TxsNum != 0 {
  117. tx = common.L1Tx{
  118. TxID: common.TxID(common.Hash([]byte("L1_" + strconv.Itoa(fromIdx+i)))),
  119. ToForgeL1TxsNum: batches[i%len(batches)].ForgeL1TxsNum,
  120. Position: i,
  121. UserOrigin: i%2 == 0,
  122. TokenID: tokens[i%len(tokens)].TokenID,
  123. Amount: big.NewInt(int64(i + 1)),
  124. LoadAmount: big.NewInt(int64(i + 1)),
  125. EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
  126. Type: randomTxType(i),
  127. }
  128. if i%4 == 0 {
  129. tx.BatchNum = batches[i%len(batches)].BatchNum
  130. }
  131. } else {
  132. continue
  133. }
  134. if i < nUserTxs {
  135. var from, to common.Account
  136. var err error
  137. if i%2 == 0 {
  138. from, err = randomAccount(i, true, userAddr, accounts)
  139. if err != nil {
  140. panic(err)
  141. }
  142. to, err = randomAccount(i, false, userAddr, accounts)
  143. if err != nil {
  144. panic(err)
  145. }
  146. } else {
  147. from, err = randomAccount(i, false, userAddr, accounts)
  148. if err != nil {
  149. panic(err)
  150. }
  151. to, err = randomAccount(i, true, userAddr, accounts)
  152. if err != nil {
  153. panic(err)
  154. }
  155. }
  156. tx.FromIdx = from.Idx
  157. tx.FromEthAddr = from.EthAddr
  158. tx.FromBJJ = from.PublicKey
  159. tx.ToIdx = to.Idx
  160. userTxs = append(userTxs, tx)
  161. } else {
  162. from, err := randomAccount(i, false, userAddr, accounts)
  163. if err != nil {
  164. panic(err)
  165. }
  166. to, err := randomAccount(i, false, userAddr, accounts)
  167. if err != nil {
  168. panic(err)
  169. }
  170. tx.FromIdx = from.Idx
  171. tx.FromEthAddr = from.EthAddr
  172. tx.FromBJJ = from.PublicKey
  173. tx.ToIdx = to.Idx
  174. othersTxs = append(othersTxs, tx)
  175. }
  176. }
  177. return userTxs, othersTxs
  178. }
  179. // GenL2Txs generates L2 txs. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
  180. func GenL2Txs(
  181. fromIdx int,
  182. totalTxs, nUserTxs int,
  183. userAddr *ethCommon.Address,
  184. accounts []common.Account,
  185. tokens []common.Token,
  186. blocks []common.Block,
  187. batches []common.Batch,
  188. ) ([]common.L2Tx, []common.L2Tx) {
  189. if totalTxs < nUserTxs {
  190. panic("totalTxs must be greater than userTxs")
  191. }
  192. userTxs := []common.L2Tx{}
  193. othersTxs := []common.L2Tx{}
  194. for i := 0; i < totalTxs; i++ {
  195. tx := common.L2Tx{
  196. TxID: common.TxID(common.Hash([]byte("L2_" + strconv.Itoa(fromIdx+i)))),
  197. BatchNum: batches[i%len(batches)].BatchNum,
  198. Position: i,
  199. //nolint:gomnd
  200. Amount: big.NewInt(int64(i + 1)),
  201. //nolint:gomnd
  202. Fee: common.FeeSelector(i % 256),
  203. Nonce: common.Nonce(i + 1),
  204. EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
  205. Type: randomTxType(i),
  206. }
  207. if i < nUserTxs {
  208. var from, to common.Account
  209. var err error
  210. if i%2 == 0 {
  211. from, err = randomAccount(i, true, userAddr, accounts)
  212. if err != nil {
  213. panic(err)
  214. }
  215. to, err = randomAccount(i, false, userAddr, accounts)
  216. if err != nil {
  217. panic(err)
  218. }
  219. } else {
  220. from, err = randomAccount(i, false, userAddr, accounts)
  221. if err != nil {
  222. panic(err)
  223. }
  224. to, err = randomAccount(i, true, userAddr, accounts)
  225. if err != nil {
  226. panic(err)
  227. }
  228. }
  229. tx.FromIdx = from.Idx
  230. tx.ToIdx = to.Idx
  231. userTxs = append(userTxs, tx)
  232. } else {
  233. from, err := randomAccount(i, false, userAddr, accounts)
  234. if err != nil {
  235. panic(err)
  236. }
  237. to, err := randomAccount(i, false, userAddr, accounts)
  238. if err != nil {
  239. panic(err)
  240. }
  241. tx.FromIdx = from.Idx
  242. tx.ToIdx = to.Idx
  243. othersTxs = append(othersTxs, tx)
  244. }
  245. }
  246. return userTxs, othersTxs
  247. }
  248. // GenCoordinators generates coordinators. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
  249. func GenCoordinators(nCoords int, blocks []common.Block) []common.Coordinator {
  250. coords := []common.Coordinator{}
  251. for i := 0; i < nCoords; i++ {
  252. coords = append(coords, common.Coordinator{
  253. EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
  254. Forger: ethCommon.BigToAddress(big.NewInt(int64(i))),
  255. Withdraw: ethCommon.BigToAddress(big.NewInt(int64(i))),
  256. URL: "https://foo.bar",
  257. })
  258. }
  259. return coords
  260. }
  261. // GenBids generates bids. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
  262. func GenBids(nBids int, blocks []common.Block, coords []common.Coordinator) []common.Bid {
  263. bids := []common.Bid{}
  264. for i := 0; i < nBids; i++ {
  265. bids = append(bids, common.Bid{
  266. SlotNum: common.SlotNum(i),
  267. BidValue: big.NewInt(int64(i)),
  268. EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
  269. ForgerAddr: coords[i%len(blocks)].Forger,
  270. })
  271. }
  272. return bids
  273. }
  274. func randomAccount(seed int, userAccount bool, userAddr *ethCommon.Address, accs []common.Account) (common.Account, error) {
  275. i := seed % len(accs)
  276. firstI := i
  277. for {
  278. acc := accs[i]
  279. if userAccount && *userAddr == acc.EthAddr {
  280. return acc, nil
  281. }
  282. if !userAccount && (userAddr == nil || *userAddr != acc.EthAddr) {
  283. return acc, nil
  284. }
  285. i++
  286. i = i % len(accs)
  287. if i == firstI {
  288. return acc, errors.New("Didnt found any account matchinng the criteria")
  289. }
  290. }
  291. }
  292. func randomTxType(seed int) common.TxType {
  293. //nolint:gomnd
  294. switch seed % 11 {
  295. case 0:
  296. return common.TxTypeExit
  297. //nolint:gomnd
  298. case 1:
  299. return common.TxTypeWithdrawn
  300. //nolint:gomnd
  301. case 2:
  302. return common.TxTypeTransfer
  303. //nolint:gomnd
  304. case 3:
  305. return common.TxTypeDeposit
  306. //nolint:gomnd
  307. case 4:
  308. return common.TxTypeCreateAccountDeposit
  309. //nolint:gomnd
  310. case 5:
  311. return common.TxTypeCreateAccountDepositTransfer
  312. //nolint:gomnd
  313. case 6:
  314. return common.TxTypeDepositTransfer
  315. //nolint:gomnd
  316. case 7:
  317. return common.TxTypeForceTransfer
  318. //nolint:gomnd
  319. case 8:
  320. return common.TxTypeForceExit
  321. //nolint:gomnd
  322. case 9:
  323. return common.TxTypeTransferToEthAddr
  324. //nolint:gomnd
  325. case 10:
  326. return common.TxTypeTransferToBJJ
  327. default:
  328. return common.TxTypeTransfer
  329. }
  330. }