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.

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