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.

434 lines
12 KiB

Update missing parts, improve til, and more - Node - Updated configuration to initialize the interface to all the smart contracts - Common - Moved BlockData and BatchData types to common so that they can be shared among: historydb, til and synchronizer - Remove hash.go (it was never used) - Remove slot.go (it was never used) - Remove smartcontractparams.go (it was never used, and appropriate structs are defined in `eth/`) - Comment state / status method until requirements of this method are properly defined, and move it to Synchronizer - Synchronizer - Simplify `Sync` routine to only sync one block per call, and return useful information. - Use BlockData and BatchData from common - Check that events belong to the expected block hash - In L1Batch, query L1UserTxs from HistoryDB - Fill ERC20 token information - Test AddTokens with test.Client - HistryDB - Use BlockData and BatchData from common - Add `GetAllTokens` method - Uncomment and update GetL1UserTxs (with corresponding tests) - Til - Rename all instances of RegisterToken to AddToken (to follow the smart contract implementation naming) - Use BlockData and BatchData from common - Move testL1CoordinatorTxs and testL2Txs to a separate struct from BatchData in Context - Start Context with BatchNum = 1 (which the protocol defines to be the first batchNum) - In every Batch, set StateRoot and ExitRoot to a non-nil big.Int (zero). - In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not used, set it to 0; so that no *big.Int is nil. - In L1UserTx, don't set BatchNum, because when L1UserTxs are created and obtained by the synchronizer, the BatchNum is not known yet (it's a synchronizer job to set it) - In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago
Update missing parts, improve til, and more - Node - Updated configuration to initialize the interface to all the smart contracts - Common - Moved BlockData and BatchData types to common so that they can be shared among: historydb, til and synchronizer - Remove hash.go (it was never used) - Remove slot.go (it was never used) - Remove smartcontractparams.go (it was never used, and appropriate structs are defined in `eth/`) - Comment state / status method until requirements of this method are properly defined, and move it to Synchronizer - Synchronizer - Simplify `Sync` routine to only sync one block per call, and return useful information. - Use BlockData and BatchData from common - Check that events belong to the expected block hash - In L1Batch, query L1UserTxs from HistoryDB - Fill ERC20 token information - Test AddTokens with test.Client - HistryDB - Use BlockData and BatchData from common - Add `GetAllTokens` method - Uncomment and update GetL1UserTxs (with corresponding tests) - Til - Rename all instances of RegisterToken to AddToken (to follow the smart contract implementation naming) - Use BlockData and BatchData from common - Move testL1CoordinatorTxs and testL2Txs to a separate struct from BatchData in Context - Start Context with BatchNum = 1 (which the protocol defines to be the first batchNum) - In every Batch, set StateRoot and ExitRoot to a non-nil big.Int (zero). - In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not used, set it to 0; so that no *big.Int is nil. - In L1UserTx, don't set BatchNum, because when L1UserTxs are created and obtained by the synchronizer, the BatchNum is not known yet (it's a synchronizer job to set it) - In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago
Update missing parts, improve til, and more - Node - Updated configuration to initialize the interface to all the smart contracts - Common - Moved BlockData and BatchData types to common so that they can be shared among: historydb, til and synchronizer - Remove hash.go (it was never used) - Remove slot.go (it was never used) - Remove smartcontractparams.go (it was never used, and appropriate structs are defined in `eth/`) - Comment state / status method until requirements of this method are properly defined, and move it to Synchronizer - Synchronizer - Simplify `Sync` routine to only sync one block per call, and return useful information. - Use BlockData and BatchData from common - Check that events belong to the expected block hash - In L1Batch, query L1UserTxs from HistoryDB - Fill ERC20 token information - Test AddTokens with test.Client - HistryDB - Use BlockData and BatchData from common - Add `GetAllTokens` method - Uncomment and update GetL1UserTxs (with corresponding tests) - Til - Rename all instances of RegisterToken to AddToken (to follow the smart contract implementation naming) - Use BlockData and BatchData from common - Move testL1CoordinatorTxs and testL2Txs to a separate struct from BatchData in Context - Start Context with BatchNum = 1 (which the protocol defines to be the first batchNum) - In every Batch, set StateRoot and ExitRoot to a non-nil big.Int (zero). - In all L1Txs, if LoadAmount is not used, set it to 0; if Amount is not used, set it to 0; so that no *big.Int is nil. - In L1UserTx, don't set BatchNum, because when L1UserTxs are created and obtained by the synchronizer, the BatchNum is not known yet (it's a synchronizer job to set it) - In L1UserTxs, set `UserOrigin` and set `ToForgeL1TxsNum`.
4 years ago
  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: "NAME" + fmt.Sprint(i),
  34. Symbol: fmt.Sprint(i),
  35. Decimals: uint64(i + 1),
  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: big.NewInt(int64(i) * 5), //nolint:gomnd
  58. //nolint:gomnd
  59. NumAccounts: 30,
  60. ExitRoot: big.NewInt(int64(i) * 16), //nolint:gomnd
  61. SlotNum: int64(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. Balance: big.NewInt(int64(i * 10000000)), //nolint:gomnd
  96. })
  97. }
  98. return accs
  99. }
  100. // GenL1Txs generates L1 txs. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
  101. func GenL1Txs(
  102. fromIdx int,
  103. totalTxs, nUserTxs int,
  104. userAddr *ethCommon.Address,
  105. accounts []common.Account,
  106. tokens []common.Token,
  107. blocks []common.Block,
  108. batches []common.Batch,
  109. ) ([]common.L1Tx, []common.L1Tx) {
  110. if totalTxs < nUserTxs {
  111. panic("totalTxs must be greater than userTxs")
  112. }
  113. userTxs := []common.L1Tx{}
  114. othersTxs := []common.L1Tx{}
  115. _, nextTxsNum := GetNextToForgeNumAndBatch(batches)
  116. for i := fromIdx; i < fromIdx+totalTxs; i++ {
  117. token := tokens[i%len(tokens)]
  118. amount := big.NewInt(int64(i + 1))
  119. tx := common.L1Tx{
  120. Position: i - fromIdx,
  121. UserOrigin: i%2 == 0,
  122. TokenID: token.TokenID,
  123. Amount: amount,
  124. LoadAmount: amount,
  125. EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
  126. }
  127. if tx.UserOrigin {
  128. n := nextTxsNum
  129. tx.ToForgeL1TxsNum = &n
  130. } else {
  131. tx.BatchNum = &batches[i%len(batches)].BatchNum
  132. }
  133. nTx, err := common.NewL1Tx(&tx)
  134. if err != nil {
  135. panic(err)
  136. }
  137. tx = *nTx
  138. if !tx.UserOrigin {
  139. tx.BatchNum = &batches[i%len(batches)].BatchNum
  140. } else if batches[i%len(batches)].ForgeL1TxsNum != nil {
  141. // Add already forged txs
  142. tx.BatchNum = &batches[i%len(batches)].BatchNum
  143. setFromToAndAppend(fromIdx, tx, i, nUserTxs, userAddr, accounts, &userTxs, &othersTxs)
  144. } else {
  145. // Add unforged txs
  146. n := nextTxsNum
  147. tx.ToForgeL1TxsNum = &n
  148. tx.UserOrigin = true
  149. setFromToAndAppend(fromIdx, tx, i, nUserTxs, userAddr, accounts, &userTxs, &othersTxs)
  150. }
  151. }
  152. return userTxs, othersTxs
  153. }
  154. // GetNextToForgeNumAndBatch returns the next BatchNum and ForgeL1TxsNum to be added
  155. func GetNextToForgeNumAndBatch(batches []common.Batch) (common.BatchNum, int64) {
  156. batchNum := batches[len(batches)-1].BatchNum + 1
  157. var toForgeL1TxsNum int64
  158. found := false
  159. for i := len(batches) - 1; i >= 0; i-- {
  160. if batches[i].ForgeL1TxsNum != nil {
  161. toForgeL1TxsNum = *batches[i].ForgeL1TxsNum + 1
  162. found = true
  163. break
  164. }
  165. }
  166. if !found {
  167. panic("toForgeL1TxsNum not found")
  168. }
  169. return batchNum, toForgeL1TxsNum
  170. }
  171. func setFromToAndAppend(
  172. fromIdx int,
  173. tx common.L1Tx,
  174. i, nUserTxs int,
  175. userAddr *ethCommon.Address,
  176. accounts []common.Account,
  177. userTxs *[]common.L1Tx,
  178. othersTxs *[]common.L1Tx,
  179. ) {
  180. if i < fromIdx+nUserTxs {
  181. var from, to *common.Account
  182. var err error
  183. if i%2 == 0 {
  184. from, err = randomAccount(i, true, userAddr, accounts)
  185. if err != nil {
  186. panic(err)
  187. }
  188. to, err = randomAccount(i, false, userAddr, accounts)
  189. if err != nil {
  190. panic(err)
  191. }
  192. } else {
  193. from, err = randomAccount(i, false, userAddr, accounts)
  194. if err != nil {
  195. panic(err)
  196. }
  197. to, err = randomAccount(i, true, userAddr, accounts)
  198. if err != nil {
  199. panic(err)
  200. }
  201. }
  202. tx.FromIdx = from.Idx
  203. tx.FromEthAddr = from.EthAddr
  204. tx.FromBJJ = from.PublicKey
  205. tx.ToIdx = to.Idx
  206. *userTxs = append(*userTxs, tx)
  207. } else {
  208. from, err := randomAccount(i, false, userAddr, accounts)
  209. if err != nil {
  210. panic(err)
  211. }
  212. to, err := randomAccount(i, false, userAddr, accounts)
  213. if err != nil {
  214. panic(err)
  215. }
  216. tx.FromIdx = from.Idx
  217. tx.FromEthAddr = from.EthAddr
  218. tx.FromBJJ = from.PublicKey
  219. tx.ToIdx = to.Idx
  220. *othersTxs = append(*othersTxs, tx)
  221. }
  222. }
  223. // GenL2Txs generates L2 txs. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
  224. func GenL2Txs(
  225. fromIdx int,
  226. totalTxs, nUserTxs int,
  227. userAddr *ethCommon.Address,
  228. accounts []common.Account,
  229. tokens []common.Token,
  230. blocks []common.Block,
  231. batches []common.Batch,
  232. ) ([]common.L2Tx, []common.L2Tx) {
  233. if totalTxs < nUserTxs {
  234. panic("totalTxs must be greater than userTxs")
  235. }
  236. userTxs := []common.L2Tx{}
  237. othersTxs := []common.L2Tx{}
  238. for i := fromIdx; i < fromIdx+totalTxs; i++ {
  239. amount := big.NewInt(int64(i + 1))
  240. fee := common.FeeSelector(i % 256) //nolint:gomnd
  241. tx := common.L2Tx{
  242. TxID: common.TxID([12]byte{2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, byte(i)}), // only for testing purposes
  243. BatchNum: batches[i%len(batches)].BatchNum,
  244. Position: i - fromIdx,
  245. Amount: amount,
  246. Fee: fee,
  247. Nonce: common.Nonce(i + 1),
  248. EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
  249. Type: randomTxType(i),
  250. }
  251. if i < nUserTxs {
  252. var from, to *common.Account
  253. var err error
  254. if i%2 == 0 {
  255. from, err = randomAccount(i, true, userAddr, accounts)
  256. if err != nil {
  257. panic(err)
  258. }
  259. to, err = randomAccount(i, false, userAddr, accounts)
  260. if err != nil {
  261. panic(err)
  262. }
  263. } else {
  264. from, err = randomAccount(i, false, userAddr, accounts)
  265. if err != nil {
  266. panic(err)
  267. }
  268. to, err = randomAccount(i, true, userAddr, accounts)
  269. if err != nil {
  270. panic(err)
  271. }
  272. }
  273. tx.FromIdx = from.Idx
  274. tx.ToIdx = to.Idx
  275. } else {
  276. from, err := randomAccount(i, false, userAddr, accounts)
  277. if err != nil {
  278. panic(err)
  279. }
  280. to, err := randomAccount(i, false, userAddr, accounts)
  281. if err != nil {
  282. panic(err)
  283. }
  284. tx.FromIdx = from.Idx
  285. tx.ToIdx = to.Idx
  286. }
  287. if i < nUserTxs {
  288. userTxs = append(userTxs, tx)
  289. } else {
  290. othersTxs = append(othersTxs, tx)
  291. }
  292. }
  293. return userTxs, othersTxs
  294. }
  295. // GenCoordinators generates coordinators. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
  296. func GenCoordinators(nCoords int, blocks []common.Block) []common.Coordinator {
  297. coords := []common.Coordinator{}
  298. for i := 0; i < nCoords; i++ {
  299. coords = append(coords, common.Coordinator{
  300. EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
  301. Forger: ethCommon.BigToAddress(big.NewInt(int64(i))),
  302. Bidder: ethCommon.BigToAddress(big.NewInt(int64(i))),
  303. URL: "https://foo.bar",
  304. })
  305. }
  306. return coords
  307. }
  308. // GenBids generates bids. WARNING: This is meant for DB/API testing, and may not be fully consistent with the protocol.
  309. func GenBids(nBids int, blocks []common.Block, coords []common.Coordinator) []common.Bid {
  310. bids := []common.Bid{}
  311. for i := 0; i < nBids; i++ {
  312. bids = append(bids, common.Bid{
  313. SlotNum: int64(i),
  314. BidValue: big.NewInt(int64(i)),
  315. EthBlockNum: blocks[i%len(blocks)].EthBlockNum,
  316. Bidder: coords[i%len(blocks)].Bidder,
  317. })
  318. }
  319. return bids
  320. }
  321. // GenExitTree generates an exitTree (as an array of Exits)
  322. //nolint:gomnd
  323. func GenExitTree(n int, batches []common.Batch, accounts []common.Account) []common.ExitInfo {
  324. exitTree := make([]common.ExitInfo, n)
  325. for i := 0; i < n; i++ {
  326. exitTree[i] = common.ExitInfo{
  327. BatchNum: batches[i%len(batches)].BatchNum,
  328. InstantWithdrawn: nil,
  329. DelayedWithdrawRequest: nil,
  330. DelayedWithdrawn: nil,
  331. AccountIdx: accounts[i%len(accounts)].Idx,
  332. MerkleProof: &merkletree.CircomVerifierProof{
  333. Root: &merkletree.Hash{byte(i), byte(i + 1)},
  334. Siblings: []*big.Int{
  335. big.NewInt(int64(i) * 10),
  336. big.NewInt(int64(i)*100 + 1),
  337. big.NewInt(int64(i)*1000 + 2)},
  338. OldKey: &merkletree.Hash{byte(i * 1), byte(i*1 + 1)},
  339. OldValue: &merkletree.Hash{byte(i * 2), byte(i*2 + 1)},
  340. IsOld0: i%2 == 0,
  341. Key: &merkletree.Hash{byte(i * 3), byte(i*3 + 1)},
  342. Value: &merkletree.Hash{byte(i * 4), byte(i*4 + 1)},
  343. Fnc: i % 2,
  344. },
  345. Balance: big.NewInt(int64(i) * 1000),
  346. }
  347. if i%2 == 0 {
  348. instant := new(int64)
  349. *instant = int64(batches[(i+1)%len(batches)].BatchNum)
  350. exitTree[i].InstantWithdrawn = instant
  351. } else if i%3 == 0 {
  352. delayedReq := new(int64)
  353. *delayedReq = int64(batches[(i+1)%len(batches)].BatchNum)
  354. exitTree[i].DelayedWithdrawRequest = delayedReq
  355. if i%9 == 0 {
  356. delayed := new(int64)
  357. *delayed = int64(batches[(i+2)%len(batches)].BatchNum)
  358. exitTree[i].DelayedWithdrawn = delayed
  359. }
  360. }
  361. }
  362. return exitTree
  363. }
  364. func randomAccount(seed int, userAccount bool, userAddr *ethCommon.Address, accs []common.Account) (*common.Account, error) {
  365. i := seed % len(accs)
  366. firstI := i
  367. for {
  368. acc := accs[i]
  369. if userAccount && *userAddr == acc.EthAddr {
  370. return &acc, nil
  371. }
  372. if !userAccount && (userAddr == nil || *userAddr != acc.EthAddr) {
  373. return &acc, nil
  374. }
  375. i++
  376. i = i % len(accs)
  377. if i == firstI {
  378. return &acc, errors.New("Didnt found any account matchinng the criteria")
  379. }
  380. }
  381. }
  382. func randomTxType(seed int) common.TxType {
  383. //nolint:gomnd
  384. switch seed % 11 {
  385. case 0:
  386. return common.TxTypeExit
  387. //nolint:gomnd
  388. case 2:
  389. return common.TxTypeTransfer
  390. //nolint:gomnd
  391. case 3:
  392. return common.TxTypeDeposit
  393. //nolint:gomnd
  394. case 4:
  395. return common.TxTypeCreateAccountDeposit
  396. //nolint:gomnd
  397. case 5:
  398. return common.TxTypeCreateAccountDepositTransfer
  399. //nolint:gomnd
  400. case 6:
  401. return common.TxTypeDepositTransfer
  402. //nolint:gomnd
  403. case 7:
  404. return common.TxTypeForceTransfer
  405. //nolint:gomnd
  406. case 8:
  407. return common.TxTypeForceExit
  408. //nolint:gomnd
  409. case 9:
  410. return common.TxTypeTransferToEthAddr
  411. //nolint:gomnd
  412. case 10:
  413. return common.TxTypeTransferToBJJ
  414. default:
  415. return common.TxTypeTransfer
  416. }
  417. }