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.

345 lines
9.5 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, userBjj *babyjub.PublicKey, batches []common.Batch) []common.Account {
  76. if totalAccounts < userAccounts {
  77. panic("totalAccounts must be greater than userAccounts")
  78. }
  79. accs := []common.Account{}
  80. for i := 0; i < totalAccounts; i++ {
  81. var addr ethCommon.Address
  82. var pubK *babyjub.PublicKey
  83. if i < userAccounts {
  84. addr = *userAddr
  85. pubK = userBjj
  86. } else {
  87. addr = ethCommon.BigToAddress(big.NewInt(int64(i)))
  88. privK := babyjub.NewRandPrivKey()
  89. pubK = privK.Public()
  90. }
  91. accs = append(accs, common.Account{
  92. Idx: common.Idx(i),
  93. TokenID: tokens[i%len(tokens)].TokenID,
  94. EthAddr: addr,
  95. BatchNum: batches[i%len(batches)].BatchNum,
  96. PublicKey: pubK,
  97. })
  98. }
  99. return accs
  100. }
  101. // GenL1Txs generates L1 txs. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
  102. func GenL1Txs(
  103. fromIdx int,
  104. totalTxs, nUserTxs int,
  105. userAddr *ethCommon.Address,
  106. accounts []common.Account,
  107. tokens []common.Token,
  108. blocks []common.Block,
  109. batches []common.Batch,
  110. ) ([]common.L1Tx, []common.L1Tx) {
  111. if totalTxs < nUserTxs {
  112. panic("totalTxs must be greater than userTxs")
  113. }
  114. userTxs := []common.L1Tx{}
  115. othersTxs := []common.L1Tx{}
  116. for i := 0; i < totalTxs; i++ {
  117. var tx common.L1Tx
  118. if batches[i%len(batches)].ForgeL1TxsNum != 0 {
  119. tx = common.L1Tx{
  120. TxID: common.TxID(common.Hash([]byte("L1_" + strconv.Itoa(fromIdx+i)))),
  121. ToForgeL1TxsNum: batches[i%len(batches)].ForgeL1TxsNum,
  122. Position: i,
  123. UserOrigin: i%2 == 0,
  124. TokenID: tokens[i%len(tokens)].TokenID,
  125. Amount: big.NewInt(int64(i + 1)),
  126. LoadAmount: big.NewInt(int64(i + 1)),
  127. EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
  128. Type: randomTxType(i),
  129. }
  130. if i%4 == 0 {
  131. tx.BatchNum = batches[i%len(batches)].BatchNum
  132. }
  133. } else {
  134. continue
  135. }
  136. if i < nUserTxs {
  137. var from, to common.Account
  138. var err error
  139. if i%2 == 0 {
  140. from, err = randomAccount(i, true, userAddr, accounts)
  141. if err != nil {
  142. panic(err)
  143. }
  144. to, err = randomAccount(i, false, userAddr, accounts)
  145. if err != nil {
  146. panic(err)
  147. }
  148. } else {
  149. from, err = randomAccount(i, false, userAddr, accounts)
  150. if err != nil {
  151. panic(err)
  152. }
  153. to, err = randomAccount(i, true, userAddr, accounts)
  154. if err != nil {
  155. panic(err)
  156. }
  157. }
  158. tx.FromIdx = from.Idx
  159. tx.FromEthAddr = from.EthAddr
  160. tx.FromBJJ = from.PublicKey
  161. tx.ToIdx = to.Idx
  162. userTxs = append(userTxs, tx)
  163. } else {
  164. from, err := randomAccount(i, false, userAddr, accounts)
  165. if err != nil {
  166. panic(err)
  167. }
  168. to, err := randomAccount(i, false, userAddr, accounts)
  169. if err != nil {
  170. panic(err)
  171. }
  172. tx.FromIdx = from.Idx
  173. tx.FromEthAddr = from.EthAddr
  174. tx.FromBJJ = from.PublicKey
  175. tx.ToIdx = to.Idx
  176. othersTxs = append(othersTxs, tx)
  177. }
  178. }
  179. return userTxs, othersTxs
  180. }
  181. // GenL2Txs generates L2 txs. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
  182. func GenL2Txs(
  183. fromIdx int,
  184. totalTxs, nUserTxs int,
  185. userAddr *ethCommon.Address,
  186. accounts []common.Account,
  187. tokens []common.Token,
  188. blocks []common.Block,
  189. batches []common.Batch,
  190. ) ([]common.L2Tx, []common.L2Tx) {
  191. if totalTxs < nUserTxs {
  192. panic("totalTxs must be greater than userTxs")
  193. }
  194. userTxs := []common.L2Tx{}
  195. othersTxs := []common.L2Tx{}
  196. for i := 0; i < totalTxs; i++ {
  197. tx := common.L2Tx{
  198. TxID: common.TxID(common.Hash([]byte("L2_" + strconv.Itoa(fromIdx+i)))),
  199. BatchNum: batches[i%len(batches)].BatchNum,
  200. Position: i,
  201. //nolint:gomnd
  202. Amount: big.NewInt(int64(i + 1)),
  203. //nolint:gomnd
  204. Fee: common.FeeSelector(i % 256),
  205. Nonce: common.Nonce(i + 1),
  206. EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
  207. Type: randomTxType(i),
  208. }
  209. if i < nUserTxs {
  210. var from, to common.Account
  211. var err error
  212. if i%2 == 0 {
  213. from, err = randomAccount(i, true, userAddr, accounts)
  214. if err != nil {
  215. panic(err)
  216. }
  217. to, err = randomAccount(i, false, userAddr, accounts)
  218. if err != nil {
  219. panic(err)
  220. }
  221. } else {
  222. from, err = randomAccount(i, false, userAddr, accounts)
  223. if err != nil {
  224. panic(err)
  225. }
  226. to, err = randomAccount(i, true, userAddr, accounts)
  227. if err != nil {
  228. panic(err)
  229. }
  230. }
  231. tx.FromIdx = from.Idx
  232. tx.ToIdx = to.Idx
  233. userTxs = append(userTxs, tx)
  234. } else {
  235. from, err := randomAccount(i, false, userAddr, accounts)
  236. if err != nil {
  237. panic(err)
  238. }
  239. to, err := randomAccount(i, false, userAddr, accounts)
  240. if err != nil {
  241. panic(err)
  242. }
  243. tx.FromIdx = from.Idx
  244. tx.ToIdx = to.Idx
  245. othersTxs = append(othersTxs, tx)
  246. }
  247. }
  248. return userTxs, othersTxs
  249. }
  250. // GenCoordinators generates coordinators. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
  251. func GenCoordinators(nCoords int, blocks []common.Block) []common.Coordinator {
  252. coords := []common.Coordinator{}
  253. for i := 0; i < nCoords; i++ {
  254. coords = append(coords, common.Coordinator{
  255. EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
  256. Forger: ethCommon.BigToAddress(big.NewInt(int64(i))),
  257. Withdraw: ethCommon.BigToAddress(big.NewInt(int64(i))),
  258. URL: "https://foo.bar",
  259. })
  260. }
  261. return coords
  262. }
  263. // GenBids generates bids. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
  264. func GenBids(nBids int, blocks []common.Block, coords []common.Coordinator) []common.Bid {
  265. bids := []common.Bid{}
  266. for i := 0; i < nBids; i++ {
  267. bids = append(bids, common.Bid{
  268. SlotNum: common.SlotNum(i),
  269. BidValue: big.NewInt(int64(i)),
  270. EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
  271. ForgerAddr: coords[i%len(blocks)].Forger,
  272. })
  273. }
  274. return bids
  275. }
  276. func randomAccount(seed int, userAccount bool, userAddr *ethCommon.Address, accs []common.Account) (common.Account, error) {
  277. i := seed % len(accs)
  278. firstI := i
  279. for {
  280. acc := accs[i]
  281. if userAccount && *userAddr == acc.EthAddr {
  282. return acc, nil
  283. }
  284. if !userAccount && (userAddr == nil || *userAddr != acc.EthAddr) {
  285. return acc, nil
  286. }
  287. i++
  288. i = i % len(accs)
  289. if i == firstI {
  290. return acc, errors.New("Didnt found any account matchinng the criteria")
  291. }
  292. }
  293. }
  294. func randomTxType(seed int) common.TxType {
  295. //nolint:gomnd
  296. switch seed % 11 {
  297. case 0:
  298. return common.TxTypeExit
  299. //nolint:gomnd
  300. case 1:
  301. return common.TxTypeWithdrawn
  302. //nolint:gomnd
  303. case 2:
  304. return common.TxTypeTransfer
  305. //nolint:gomnd
  306. case 3:
  307. return common.TxTypeDeposit
  308. //nolint:gomnd
  309. case 4:
  310. return common.TxTypeCreateAccountDeposit
  311. //nolint:gomnd
  312. case 5:
  313. return common.TxTypeCreateAccountDepositTransfer
  314. //nolint:gomnd
  315. case 6:
  316. return common.TxTypeDepositTransfer
  317. //nolint:gomnd
  318. case 7:
  319. return common.TxTypeForceTransfer
  320. //nolint:gomnd
  321. case 8:
  322. return common.TxTypeForceExit
  323. //nolint:gomnd
  324. case 9:
  325. return common.TxTypeTransferToEthAddr
  326. //nolint:gomnd
  327. case 10:
  328. return common.TxTypeTransferToBJJ
  329. default:
  330. return common.TxTypeTransfer
  331. }
  332. }