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.

483 lines
14 KiB

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