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.

868 lines
28 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
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
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
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
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
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
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 til
  2. import (
  3. "crypto/ecdsa"
  4. "fmt"
  5. "math/big"
  6. "strconv"
  7. "strings"
  8. "time"
  9. ethCommon "github.com/ethereum/go-ethereum/common"
  10. ethCrypto "github.com/ethereum/go-ethereum/crypto"
  11. "github.com/hermeznetwork/hermez-node/common"
  12. "github.com/hermeznetwork/hermez-node/log"
  13. "github.com/iden3/go-iden3-crypto/babyjub"
  14. )
  15. func newBatchData(batchNum int) common.BatchData {
  16. return common.BatchData{
  17. L1CoordinatorTxs: []common.L1Tx{},
  18. L2Txs: []common.L2Tx{},
  19. Batch: common.Batch{
  20. BatchNum: common.BatchNum(batchNum),
  21. StateRoot: big.NewInt(0), ExitRoot: big.NewInt(0),
  22. FeeIdxsCoordinator: make([]common.Idx, 0),
  23. CollectedFees: make(map[common.TokenID]*big.Int),
  24. },
  25. }
  26. }
  27. func newBlock(blockNum int64) common.BlockData {
  28. return common.BlockData{
  29. Block: common.Block{
  30. EthBlockNum: blockNum,
  31. },
  32. Rollup: common.RollupData{
  33. L1UserTxs: []common.L1Tx{},
  34. },
  35. }
  36. }
  37. type contextExtra struct {
  38. openToForge int64
  39. toForgeL1TxsNum int64
  40. nonces map[common.Idx]common.Nonce
  41. idx int
  42. }
  43. // Context contains the data of the test
  44. type Context struct {
  45. Instructions []instruction
  46. userNames []string
  47. Users map[string]*User // Name -> *User
  48. UsersByIdx map[int]*User
  49. accountsByIdx map[int]*Account
  50. LastRegisteredTokenID common.TokenID
  51. l1CreatedAccounts map[string]*Account // (Name, TokenID) -> *Account
  52. // rollupConstMaxL1UserTx Maximum L1-user transactions allowed to be queued in a batch
  53. rollupConstMaxL1UserTx int
  54. idx int
  55. currBlock common.BlockData
  56. currBatch common.BatchData
  57. currBatchNum int
  58. Queues [][]L1Tx
  59. ToForgeNum int
  60. openToForge int
  61. currBatchTest struct {
  62. l1CoordinatorTxs []L1Tx
  63. l2Txs []L2Tx
  64. }
  65. blockNum int64
  66. extra contextExtra
  67. }
  68. // NewContext returns a new Context
  69. func NewContext(rollupConstMaxL1UserTx int) *Context {
  70. currBatchNum := 1 // The protocol defines the first batchNum to be 1
  71. return &Context{
  72. Users: make(map[string]*User),
  73. l1CreatedAccounts: make(map[string]*Account),
  74. UsersByIdx: make(map[int]*User),
  75. accountsByIdx: make(map[int]*Account),
  76. LastRegisteredTokenID: 0,
  77. rollupConstMaxL1UserTx: rollupConstMaxL1UserTx,
  78. idx: common.UserThreshold,
  79. // We use some placeholder values for StateRoot and ExitTree
  80. // because these values will never be nil
  81. currBlock: newBlock(2), //nolint:gomnd
  82. currBatch: newBatchData(currBatchNum),
  83. currBatchNum: currBatchNum,
  84. // start with 2 queues, one for toForge, and the other for openToForge
  85. Queues: make([][]L1Tx, 2),
  86. ToForgeNum: 0,
  87. openToForge: 1,
  88. //nolint:gomnd
  89. blockNum: 2, // rollup genesis blockNum
  90. extra: contextExtra{
  91. openToForge: 0,
  92. toForgeL1TxsNum: 0,
  93. nonces: make(map[common.Idx]common.Nonce),
  94. idx: common.UserThreshold,
  95. },
  96. }
  97. }
  98. // Account contains the data related to the account for a specific TokenID of a User
  99. type Account struct {
  100. Idx common.Idx
  101. TokenID common.TokenID
  102. Nonce common.Nonce
  103. BatchNum int
  104. }
  105. // User contains the data related to a testing user
  106. type User struct {
  107. Name string
  108. BJJ *babyjub.PrivateKey
  109. Addr ethCommon.Address
  110. Accounts map[common.TokenID]*Account
  111. }
  112. // L1Tx is the data structure used internally for transaction test generation,
  113. // which contains a common.L1Tx data plus some intermediate data for the
  114. // transaction generation.
  115. type L1Tx struct {
  116. lineNum int
  117. fromIdxName string
  118. toIdxName string
  119. L1Tx common.L1Tx
  120. }
  121. // L2Tx is the data structure used internally for transaction test generation,
  122. // which contains a common.L2Tx data plus some intermediate data for the
  123. // transaction generation.
  124. type L2Tx struct {
  125. lineNum int
  126. fromIdxName string
  127. toIdxName string
  128. tokenID common.TokenID
  129. L2Tx common.L2Tx
  130. }
  131. // GenerateBlocks returns an array of BlockData for a given set. It uses the
  132. // users (keys & nonces) of the Context.
  133. func (tc *Context) GenerateBlocks(set string) ([]common.BlockData, error) {
  134. parser := newParser(strings.NewReader(set))
  135. parsedSet, err := parser.parse()
  136. if err != nil {
  137. return nil, err
  138. }
  139. if parsedSet.typ != setTypeBlockchain {
  140. return nil, fmt.Errorf("Expected set type: %s, found: %s", setTypeBlockchain, parsedSet.typ)
  141. }
  142. tc.Instructions = parsedSet.instructions
  143. tc.userNames = parsedSet.users
  144. tc.generateKeys(tc.userNames)
  145. var blocks []common.BlockData
  146. for _, inst := range parsedSet.instructions {
  147. switch inst.typ {
  148. case txTypeCreateAccountDepositCoordinator: // tx source: L1CoordinatorTx
  149. if err := tc.checkIfTokenIsRegistered(inst); err != nil {
  150. log.Error(err)
  151. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  152. }
  153. tx := common.L1Tx{
  154. FromEthAddr: tc.Users[inst.from].Addr,
  155. FromBJJ: tc.Users[inst.from].BJJ.Public(),
  156. TokenID: inst.tokenID,
  157. Amount: big.NewInt(0),
  158. LoadAmount: big.NewInt(0),
  159. Type: common.TxTypeCreateAccountDeposit, // as txTypeCreateAccountDepositCoordinator is not valid oustide Til package
  160. }
  161. testTx := L1Tx{
  162. lineNum: inst.lineNum,
  163. fromIdxName: inst.from,
  164. L1Tx: tx,
  165. }
  166. tc.currBatchTest.l1CoordinatorTxs = append(tc.currBatchTest.l1CoordinatorTxs, testTx)
  167. case common.TxTypeCreateAccountDeposit, common.TxTypeCreateAccountDepositTransfer: // tx source: L1UserTx
  168. if err := tc.checkIfTokenIsRegistered(inst); err != nil {
  169. log.Error(err)
  170. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  171. }
  172. tx := common.L1Tx{
  173. FromEthAddr: tc.Users[inst.from].Addr,
  174. FromBJJ: tc.Users[inst.from].BJJ.Public(),
  175. TokenID: inst.tokenID,
  176. Amount: big.NewInt(0),
  177. LoadAmount: big.NewInt(int64(inst.loadAmount)),
  178. Type: inst.typ,
  179. }
  180. if inst.typ == common.TxTypeCreateAccountDepositTransfer {
  181. tx.Amount = big.NewInt(int64(inst.amount))
  182. }
  183. testTx := L1Tx{
  184. lineNum: inst.lineNum,
  185. fromIdxName: inst.from,
  186. toIdxName: inst.to,
  187. L1Tx: tx,
  188. }
  189. if err := tc.addToL1Queue(testTx); err != nil {
  190. return nil, err
  191. }
  192. case common.TxTypeDeposit, common.TxTypeDepositTransfer: // tx source: L1UserTx
  193. if err := tc.checkIfTokenIsRegistered(inst); err != nil {
  194. log.Error(err)
  195. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  196. }
  197. if err := tc.checkIfAccountExists(inst.from, inst); err != nil {
  198. log.Error(err)
  199. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  200. }
  201. tx := common.L1Tx{
  202. TokenID: inst.tokenID,
  203. Amount: big.NewInt(0),
  204. LoadAmount: big.NewInt(int64(inst.loadAmount)),
  205. Type: inst.typ,
  206. }
  207. if inst.typ == common.TxTypeDepositTransfer {
  208. tx.Amount = big.NewInt(int64(inst.amount))
  209. }
  210. testTx := L1Tx{
  211. lineNum: inst.lineNum,
  212. fromIdxName: inst.from,
  213. toIdxName: inst.to,
  214. L1Tx: tx,
  215. }
  216. if err := tc.addToL1Queue(testTx); err != nil {
  217. return nil, err
  218. }
  219. case common.TxTypeTransfer: // L2Tx
  220. if err := tc.checkIfTokenIsRegistered(inst); err != nil {
  221. log.Error(err)
  222. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  223. }
  224. tx := common.L2Tx{
  225. Amount: big.NewInt(int64(inst.amount)),
  226. Fee: common.FeeSelector(inst.fee),
  227. Type: common.TxTypeTransfer,
  228. EthBlockNum: tc.blockNum,
  229. }
  230. tx.BatchNum = common.BatchNum(tc.currBatchNum) // when converted to PoolL2Tx BatchNum parameter is lost
  231. testTx := L2Tx{
  232. lineNum: inst.lineNum,
  233. fromIdxName: inst.from,
  234. toIdxName: inst.to,
  235. tokenID: inst.tokenID,
  236. L2Tx: tx,
  237. }
  238. tc.currBatchTest.l2Txs = append(tc.currBatchTest.l2Txs, testTx)
  239. case common.TxTypeForceTransfer: // tx source: L1UserTx
  240. if err := tc.checkIfTokenIsRegistered(inst); err != nil {
  241. log.Error(err)
  242. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  243. }
  244. tx := common.L1Tx{
  245. TokenID: inst.tokenID,
  246. Amount: big.NewInt(int64(inst.amount)),
  247. LoadAmount: big.NewInt(0),
  248. Type: common.TxTypeForceTransfer,
  249. }
  250. testTx := L1Tx{
  251. lineNum: inst.lineNum,
  252. fromIdxName: inst.from,
  253. toIdxName: inst.to,
  254. L1Tx: tx,
  255. }
  256. if err := tc.addToL1Queue(testTx); err != nil {
  257. return nil, err
  258. }
  259. case common.TxTypeExit: // tx source: L2Tx
  260. if err := tc.checkIfTokenIsRegistered(inst); err != nil {
  261. log.Error(err)
  262. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  263. }
  264. tx := common.L2Tx{
  265. ToIdx: common.Idx(1), // as is an Exit
  266. Fee: common.FeeSelector(inst.fee),
  267. Amount: big.NewInt(int64(inst.amount)),
  268. Type: common.TxTypeExit,
  269. EthBlockNum: tc.blockNum,
  270. }
  271. tx.BatchNum = common.BatchNum(tc.currBatchNum) // when converted to PoolL2Tx BatchNum parameter is lost
  272. testTx := L2Tx{
  273. lineNum: inst.lineNum,
  274. fromIdxName: inst.from,
  275. toIdxName: inst.to,
  276. tokenID: inst.tokenID,
  277. L2Tx: tx,
  278. }
  279. tc.currBatchTest.l2Txs = append(tc.currBatchTest.l2Txs, testTx)
  280. case common.TxTypeForceExit: // tx source: L1UserTx
  281. if err := tc.checkIfTokenIsRegistered(inst); err != nil {
  282. log.Error(err)
  283. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  284. }
  285. tx := common.L1Tx{
  286. ToIdx: common.Idx(1), // as is an Exit
  287. TokenID: inst.tokenID,
  288. Amount: big.NewInt(int64(inst.amount)),
  289. LoadAmount: big.NewInt(0),
  290. Type: common.TxTypeForceExit,
  291. }
  292. testTx := L1Tx{
  293. lineNum: inst.lineNum,
  294. fromIdxName: inst.from,
  295. toIdxName: inst.to,
  296. L1Tx: tx,
  297. }
  298. if err := tc.addToL1Queue(testTx); err != nil {
  299. return nil, err
  300. }
  301. case typeNewBatch:
  302. if err = tc.calculateIdxForL1Txs(true, tc.currBatchTest.l1CoordinatorTxs); err != nil {
  303. return nil, err
  304. }
  305. if err = tc.setIdxs(); err != nil {
  306. log.Error(err)
  307. return nil, err
  308. }
  309. case typeNewBatchL1:
  310. // for each L1UserTx of the Queues[ToForgeNum], calculate the Idx
  311. if err = tc.calculateIdxForL1Txs(false, tc.Queues[tc.ToForgeNum]); err != nil {
  312. return nil, err
  313. }
  314. if err = tc.calculateIdxForL1Txs(true, tc.currBatchTest.l1CoordinatorTxs); err != nil {
  315. return nil, err
  316. }
  317. tc.currBatch.L1Batch = true
  318. if err = tc.setIdxs(); err != nil {
  319. log.Error(err)
  320. return nil, err
  321. }
  322. toForgeL1TxsNum := int64(tc.openToForge)
  323. tc.currBatch.Batch.ForgeL1TxsNum = &toForgeL1TxsNum
  324. // advance batch
  325. tc.ToForgeNum++
  326. if tc.ToForgeNum == tc.openToForge {
  327. tc.openToForge++
  328. newQueue := []L1Tx{}
  329. tc.Queues = append(tc.Queues, newQueue)
  330. }
  331. case typeNewBlock:
  332. blocks = append(blocks, tc.currBlock)
  333. tc.blockNum++
  334. tc.currBlock = newBlock(tc.blockNum)
  335. case typeAddToken:
  336. newToken := common.Token{
  337. EthAddr: ethCommon.BigToAddress(big.NewInt(int64(inst.tokenID * 100))), //nolint:gomnd
  338. // Name: fmt.Sprintf("Token %d", inst.tokenID),
  339. // Symbol: fmt.Sprintf("TK%d", inst.tokenID),
  340. // Decimals: 18,
  341. TokenID: inst.tokenID,
  342. EthBlockNum: tc.blockNum,
  343. }
  344. if inst.tokenID != tc.LastRegisteredTokenID+1 {
  345. return nil, fmt.Errorf("Line %d: AddToken TokenID should be sequential, expected TokenID: %d, defined TokenID: %d", inst.lineNum, tc.LastRegisteredTokenID+1, inst.tokenID)
  346. }
  347. tc.LastRegisteredTokenID++
  348. tc.currBlock.Rollup.AddedTokens = append(tc.currBlock.Rollup.AddedTokens, newToken)
  349. default:
  350. return nil, fmt.Errorf("Line %d: Unexpected type: %s", inst.lineNum, inst.typ)
  351. }
  352. }
  353. return blocks, nil
  354. }
  355. // calculateIdxsForL1Txs calculates new Idx for new created accounts. If
  356. // 'isCoordinatorTxs==true', adds the tx to tc.currBatch.L1CoordinatorTxs.
  357. func (tc *Context) calculateIdxForL1Txs(isCoordinatorTxs bool, txs []L1Tx) error {
  358. // for each batch.L1CoordinatorTxs of the Queues[ToForgeNum], calculate the Idx
  359. for i := 0; i < len(txs); i++ {
  360. tx := txs[i]
  361. if tx.L1Tx.Type == common.TxTypeCreateAccountDeposit || tx.L1Tx.Type == common.TxTypeCreateAccountDepositTransfer {
  362. if tc.Users[tx.fromIdxName].Accounts[tx.L1Tx.TokenID] != nil { // if account already exists, return error
  363. return fmt.Errorf("Can not create same account twice (same User (%s) & same TokenID (%d)) (this is a design property of Til)", tx.fromIdxName, tx.L1Tx.TokenID)
  364. }
  365. tc.Users[tx.fromIdxName].Accounts[tx.L1Tx.TokenID] = &Account{
  366. Idx: common.Idx(tc.idx),
  367. TokenID: tx.L1Tx.TokenID,
  368. Nonce: common.Nonce(0),
  369. BatchNum: tc.currBatchNum,
  370. }
  371. tc.l1CreatedAccounts[idxTokenIDToString(tx.fromIdxName, tx.L1Tx.TokenID)] = tc.Users[tx.fromIdxName].Accounts[tx.L1Tx.TokenID]
  372. tc.accountsByIdx[tc.idx] = tc.Users[tx.fromIdxName].Accounts[tx.L1Tx.TokenID]
  373. tc.UsersByIdx[tc.idx] = tc.Users[tx.fromIdxName]
  374. tc.idx++
  375. }
  376. if isCoordinatorTxs {
  377. tc.currBatch.L1CoordinatorTxs = append(tc.currBatch.L1CoordinatorTxs, tx.L1Tx)
  378. }
  379. }
  380. return nil
  381. }
  382. // setIdxs sets the Idxs to the transactions of the tc.currBatch
  383. func (tc *Context) setIdxs() error {
  384. // once Idxs are calculated, update transactions to use the new Idxs
  385. for i := 0; i < len(tc.currBatchTest.l2Txs); i++ {
  386. testTx := &tc.currBatchTest.l2Txs[i]
  387. if tc.Users[testTx.fromIdxName].Accounts[testTx.tokenID] == nil {
  388. return fmt.Errorf("Line %d: %s from User %s for TokenID %d while account not created yet", testTx.lineNum, testTx.L2Tx.Type, testTx.fromIdxName, testTx.tokenID)
  389. }
  390. if testTx.L2Tx.Type == common.TxTypeTransfer {
  391. if _, ok := tc.l1CreatedAccounts[idxTokenIDToString(testTx.toIdxName, testTx.tokenID)]; !ok {
  392. return fmt.Errorf("Line %d: Can not create Transfer for a non existing account. Batch %d, ToIdx name: %s, TokenID: %d", testTx.lineNum, tc.currBatchNum, testTx.toIdxName, testTx.tokenID)
  393. }
  394. }
  395. tc.Users[testTx.fromIdxName].Accounts[testTx.tokenID].Nonce++
  396. // next line is commented to avoid Blockchain L2Txs to have
  397. // Nonce different from 0, as from Blockchain those
  398. // transactions will come without Nonce
  399. // testTx.L2Tx.Nonce = tc.Users[testTx.fromIdxName].Accounts[testTx.tokenID].Nonce
  400. // set real Idx
  401. testTx.L2Tx.FromIdx = tc.Users[testTx.fromIdxName].Accounts[testTx.tokenID].Idx
  402. if testTx.L2Tx.Type == common.TxTypeTransfer {
  403. testTx.L2Tx.ToIdx = tc.Users[testTx.toIdxName].Accounts[testTx.tokenID].Idx
  404. }
  405. // in case Type==Exit, ToIdx=1, already set at the
  406. // GenerateBlocks main switch inside TxTypeExit case
  407. nTx, err := common.NewL2Tx(&testTx.L2Tx)
  408. if err != nil {
  409. return fmt.Errorf("Line %d: %s", testTx.lineNum, err.Error())
  410. }
  411. testTx.L2Tx = *nTx
  412. tc.currBatch.L2Txs = append(tc.currBatch.L2Txs, testTx.L2Tx)
  413. }
  414. tc.currBatch.Batch.LastIdx = int64(tc.idx - 1) // `-1` because tc.idx is the next available idx
  415. tc.currBlock.Rollup.Batches = append(tc.currBlock.Rollup.Batches, tc.currBatch)
  416. tc.currBatchNum++
  417. tc.currBatch = newBatchData(tc.currBatchNum)
  418. tc.currBatchTest.l1CoordinatorTxs = nil
  419. tc.currBatchTest.l2Txs = nil
  420. return nil
  421. }
  422. // addToL1Queue adds the L1Tx into the queue that is open and has space
  423. func (tc *Context) addToL1Queue(tx L1Tx) error {
  424. if len(tc.Queues[tc.openToForge]) >= tc.rollupConstMaxL1UserTx {
  425. // if current OpenToForge queue reached its Max, move into a
  426. // new queue
  427. tc.openToForge++
  428. newQueue := []L1Tx{}
  429. tc.Queues = append(tc.Queues, newQueue)
  430. }
  431. // Fill L1UserTx specific parameters
  432. tx.L1Tx.UserOrigin = true
  433. toForgeL1TxsNum := int64(tc.openToForge)
  434. tx.L1Tx.ToForgeL1TxsNum = &toForgeL1TxsNum
  435. tx.L1Tx.EthBlockNum = tc.blockNum
  436. tx.L1Tx.Position = len(tc.Queues[tc.openToForge])
  437. // When an L1UserTx is generated, all idxs must be available (except when idx == 0 or idx == 1)
  438. if tx.L1Tx.Type != common.TxTypeCreateAccountDeposit && tx.L1Tx.Type != common.TxTypeCreateAccountDepositTransfer {
  439. tx.L1Tx.FromIdx = tc.Users[tx.fromIdxName].Accounts[tx.L1Tx.TokenID].Idx
  440. }
  441. tx.L1Tx.FromEthAddr = tc.Users[tx.fromIdxName].Addr
  442. tx.L1Tx.FromBJJ = tc.Users[tx.fromIdxName].BJJ.Public()
  443. if tx.toIdxName == "" {
  444. tx.L1Tx.ToIdx = common.Idx(0)
  445. } else {
  446. account, ok := tc.Users[tx.toIdxName].Accounts[tx.L1Tx.TokenID]
  447. if !ok {
  448. return fmt.Errorf("Line %d: Transfer to User: %s, for TokenID: %d, "+
  449. "while account not created yet", tx.lineNum, tx.toIdxName, tx.L1Tx.TokenID)
  450. }
  451. tx.L1Tx.ToIdx = account.Idx
  452. }
  453. if tx.L1Tx.Type == common.TxTypeForceExit {
  454. tx.L1Tx.ToIdx = common.Idx(1)
  455. }
  456. nTx, err := common.NewL1Tx(&tx.L1Tx)
  457. if err != nil {
  458. return fmt.Errorf("Line %d: %s", tx.lineNum, err.Error())
  459. }
  460. tx.L1Tx = *nTx
  461. tc.Queues[tc.openToForge] = append(tc.Queues[tc.openToForge], tx)
  462. tc.currBlock.Rollup.L1UserTxs = append(tc.currBlock.Rollup.L1UserTxs, tx.L1Tx)
  463. return nil
  464. }
  465. func (tc *Context) checkIfAccountExists(tf string, inst instruction) error {
  466. if tc.Users[tf].Accounts[inst.tokenID] == nil {
  467. return fmt.Errorf("%s at User: %s, for TokenID: %d, while account not created yet", inst.typ, tf, inst.tokenID)
  468. }
  469. return nil
  470. }
  471. func (tc *Context) checkIfTokenIsRegistered(inst instruction) error {
  472. if inst.tokenID > tc.LastRegisteredTokenID {
  473. return fmt.Errorf("Can not process %s: TokenID %d not registered, last registered TokenID: %d", inst.typ, inst.tokenID, tc.LastRegisteredTokenID)
  474. }
  475. return nil
  476. }
  477. // GeneratePoolL2Txs returns an array of common.PoolL2Tx from a given set. It
  478. // uses the users (keys) of the Context.
  479. func (tc *Context) GeneratePoolL2Txs(set string) ([]common.PoolL2Tx, error) {
  480. parser := newParser(strings.NewReader(set))
  481. parsedSet, err := parser.parse()
  482. if err != nil {
  483. return nil, err
  484. }
  485. if parsedSet.typ != setTypePoolL2 {
  486. return nil, fmt.Errorf("Expected set type: %s, found: %s", setTypePoolL2, parsedSet.typ)
  487. }
  488. tc.Instructions = parsedSet.instructions
  489. tc.userNames = parsedSet.users
  490. tc.generateKeys(tc.userNames)
  491. txs := []common.PoolL2Tx{}
  492. for _, inst := range tc.Instructions {
  493. switch inst.typ {
  494. case common.TxTypeTransfer, common.TxTypeTransferToEthAddr, common.TxTypeTransferToBJJ:
  495. if err := tc.checkIfAccountExists(inst.from, inst); err != nil {
  496. log.Error(err)
  497. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  498. }
  499. if inst.typ == common.TxTypeTransfer {
  500. // if TxTypeTransfer, need to exist the ToIdx account
  501. if err := tc.checkIfAccountExists(inst.to, inst); err != nil {
  502. log.Error(err)
  503. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  504. }
  505. }
  506. tc.Users[inst.from].Accounts[inst.tokenID].Nonce++
  507. // if account of receiver does not exist, don't use
  508. // ToIdx, and use only ToEthAddr & ToBJJ
  509. tx := common.PoolL2Tx{
  510. FromIdx: tc.Users[inst.from].Accounts[inst.tokenID].Idx,
  511. TokenID: inst.tokenID,
  512. Amount: big.NewInt(int64(inst.amount)),
  513. Fee: common.FeeSelector(inst.fee),
  514. Nonce: tc.Users[inst.from].Accounts[inst.tokenID].Nonce,
  515. State: common.PoolL2TxStatePending,
  516. Timestamp: time.Now(),
  517. RqToEthAddr: common.EmptyAddr,
  518. RqToBJJ: nil,
  519. Type: inst.typ,
  520. }
  521. if tx.Type == common.TxTypeTransfer {
  522. tx.ToIdx = tc.Users[inst.to].Accounts[inst.tokenID].Idx
  523. tx.ToEthAddr = tc.Users[inst.to].Addr
  524. tx.ToBJJ = tc.Users[inst.to].BJJ.Public()
  525. } else if tx.Type == common.TxTypeTransferToEthAddr {
  526. tx.ToIdx = common.Idx(0)
  527. tx.ToEthAddr = tc.Users[inst.to].Addr
  528. } else if tx.Type == common.TxTypeTransferToBJJ {
  529. tx.ToIdx = common.Idx(0)
  530. tx.ToEthAddr = common.FFAddr
  531. tx.ToBJJ = tc.Users[inst.to].BJJ.Public()
  532. }
  533. nTx, err := common.NewPoolL2Tx(&tx)
  534. if err != nil {
  535. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  536. }
  537. tx = *nTx
  538. // perform signature and set it to tx.Signature
  539. toSign, err := tx.HashToSign()
  540. if err != nil {
  541. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  542. }
  543. sig := tc.Users[inst.from].BJJ.SignPoseidon(toSign)
  544. tx.Signature = sig.Compress()
  545. txs = append(txs, tx)
  546. case common.TxTypeExit:
  547. tc.Users[inst.from].Accounts[inst.tokenID].Nonce++
  548. tx := common.PoolL2Tx{
  549. FromIdx: tc.Users[inst.from].Accounts[inst.tokenID].Idx,
  550. ToIdx: common.Idx(1), // as is an Exit
  551. Fee: common.FeeSelector(inst.fee),
  552. TokenID: inst.tokenID,
  553. Amount: big.NewInt(int64(inst.amount)),
  554. Nonce: tc.Users[inst.from].Accounts[inst.tokenID].Nonce,
  555. State: common.PoolL2TxStatePending,
  556. Type: common.TxTypeExit,
  557. }
  558. nTx, err := common.NewPoolL2Tx(&tx)
  559. if err != nil {
  560. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  561. }
  562. tx = *nTx
  563. // perform signature and set it to tx.Signature
  564. toSign, err := tx.HashToSign()
  565. if err != nil {
  566. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  567. }
  568. sig := tc.Users[inst.from].BJJ.SignPoseidon(toSign)
  569. tx.Signature = sig.Compress()
  570. txs = append(txs, tx)
  571. default:
  572. return nil, fmt.Errorf("Line %d: instruction type unrecognized: %s", inst.lineNum, inst.typ)
  573. }
  574. }
  575. return txs, nil
  576. }
  577. // generateKeys generates BabyJubJub & Address keys for the given list of user
  578. // names in a deterministic way. This means, that for the same given
  579. // 'userNames' in a certain order, the keys will be always the same.
  580. func (tc *Context) generateKeys(userNames []string) {
  581. for i := 1; i < len(userNames)+1; i++ {
  582. if _, ok := tc.Users[userNames[i-1]]; ok {
  583. // account already created
  584. continue
  585. }
  586. // babyjubjub key
  587. var sk babyjub.PrivateKey
  588. copy(sk[:], []byte(strconv.Itoa(i))) // only for testing
  589. // eth address
  590. var key ecdsa.PrivateKey
  591. key.D = big.NewInt(int64(i)) // only for testing
  592. key.PublicKey.X, key.PublicKey.Y = ethCrypto.S256().ScalarBaseMult(key.D.Bytes())
  593. key.Curve = ethCrypto.S256()
  594. addr := ethCrypto.PubkeyToAddress(key.PublicKey)
  595. u := User{
  596. Name: userNames[i-1],
  597. BJJ: &sk,
  598. Addr: addr,
  599. Accounts: make(map[common.TokenID]*Account),
  600. }
  601. tc.Users[userNames[i-1]] = &u
  602. }
  603. }
  604. // L1TxsToCommonL1Txs converts an array of []til.L1Tx to []common.L1Tx
  605. func L1TxsToCommonL1Txs(l1 []L1Tx) []common.L1Tx {
  606. var r []common.L1Tx
  607. for i := 0; i < len(l1); i++ {
  608. r = append(r, l1[i].L1Tx)
  609. }
  610. return r
  611. }
  612. // ConfigExtra is the configuration used in FillBlocksExtra to extend the
  613. // blocks returned by til.
  614. type ConfigExtra struct {
  615. // Address to set as forger for each batch
  616. BootCoordAddr ethCommon.Address
  617. // Coordinator user name used to select the corresponding accounts to
  618. // collect coordinator fees
  619. CoordUser string
  620. }
  621. // FillBlocksL1UserTxsBatchNum fills the BatchNum of forged L1UserTxs:
  622. // - blocks[].Rollup.L1UserTxs[].BatchNum
  623. func (tc *Context) FillBlocksL1UserTxsBatchNum(blocks []common.BlockData) {
  624. for i := range blocks {
  625. block := &blocks[i]
  626. for j := range block.Rollup.Batches {
  627. batch := &block.Rollup.Batches[j]
  628. if batch.L1Batch {
  629. // Set BatchNum for forged L1UserTxs to til blocks
  630. bn := batch.Batch.BatchNum
  631. for k := range blocks {
  632. block := &blocks[k]
  633. for l := range block.Rollup.L1UserTxs {
  634. tx := &block.Rollup.L1UserTxs[l]
  635. if *tx.ToForgeL1TxsNum == tc.extra.openToForge {
  636. tx.BatchNum = &bn
  637. }
  638. }
  639. }
  640. tc.extra.openToForge++
  641. }
  642. }
  643. }
  644. }
  645. // FillBlocksExtra fills extra fields not generated by til in each block, so
  646. // that the blockData is closer to what the HistoryDB stores. The filled fields are:
  647. // - blocks[].Rollup.Batch.EthBlockNum
  648. // - blocks[].Rollup.Batch.ForgerAddr
  649. // - blocks[].Rollup.Batch.ForgeL1TxsNum
  650. // - blocks[].Rollup.Batch.L1CoordinatorTxs[].TxID
  651. // - blocks[].Rollup.Batch.L1CoordinatorTxs[].BatchNum
  652. // - blocks[].Rollup.Batch.L1CoordinatorTxs[].EthBlockNum
  653. // - blocks[].Rollup.Batch.L1CoordinatorTxs[].Position
  654. // - blocks[].Rollup.Batch.L2Txs[].TxID
  655. // - blocks[].Rollup.Batch.L2Txs[].Position
  656. // - blocks[].Rollup.Batch.L2Txs[].Nonce
  657. // - blocks[].Rollup.Batch.ExitTree
  658. // - blocks[].Rollup.Batch.CreatedAccounts
  659. // - blocks[].Rollup.Batch.FeeIdxCoordinator
  660. // - blocks[].Rollup.Batch.CollectedFees
  661. func (tc *Context) FillBlocksExtra(blocks []common.BlockData, cfg *ConfigExtra) error {
  662. // Fill extra fields not generated by til in til block
  663. for i := range blocks {
  664. block := &blocks[i]
  665. for j := range block.Rollup.Batches {
  666. batch := &block.Rollup.Batches[j]
  667. batch.Batch.EthBlockNum = block.Block.EthBlockNum
  668. // til doesn't fill the batch forger addr
  669. batch.Batch.ForgerAddr = cfg.BootCoordAddr
  670. if batch.L1Batch {
  671. toForgeL1TxsNumCpy := tc.extra.toForgeL1TxsNum
  672. // til doesn't fill the ForgeL1TxsNum
  673. batch.Batch.ForgeL1TxsNum = &toForgeL1TxsNumCpy
  674. tc.extra.toForgeL1TxsNum++
  675. }
  676. batchNum := batch.Batch.BatchNum
  677. for k := range batch.L1CoordinatorTxs {
  678. tx := &batch.L1CoordinatorTxs[k]
  679. tx.BatchNum = &batchNum
  680. tx.EthBlockNum = batch.Batch.EthBlockNum
  681. }
  682. }
  683. }
  684. // Fill CreatedAccounts
  685. for i := range blocks {
  686. block := &blocks[i]
  687. for j := range block.Rollup.Batches {
  688. batch := &block.Rollup.Batches[j]
  689. l1Txs := []common.L1Tx{}
  690. if batch.L1Batch {
  691. for _, tx := range tc.Queues[*batch.Batch.ForgeL1TxsNum] {
  692. l1Txs = append(l1Txs, tx.L1Tx)
  693. }
  694. }
  695. l1Txs = append(l1Txs, batch.L1CoordinatorTxs...)
  696. for k := range l1Txs {
  697. tx := &l1Txs[k]
  698. if tx.Type == common.TxTypeCreateAccountDeposit ||
  699. tx.Type == common.TxTypeCreateAccountDepositTransfer {
  700. user, ok := tc.UsersByIdx[tc.extra.idx]
  701. if !ok {
  702. return fmt.Errorf("Created account with idx: %v not found", tc.extra.idx)
  703. }
  704. batch.CreatedAccounts = append(batch.CreatedAccounts,
  705. common.Account{
  706. Idx: common.Idx(tc.extra.idx),
  707. TokenID: tx.TokenID,
  708. BatchNum: batch.Batch.BatchNum,
  709. PublicKey: user.BJJ.Public(),
  710. EthAddr: user.Addr,
  711. Nonce: 0,
  712. Balance: big.NewInt(0),
  713. })
  714. tc.extra.idx++
  715. }
  716. }
  717. }
  718. }
  719. // Fill expected positions in L1CoordinatorTxs and L2Txs
  720. for i := range blocks {
  721. block := &blocks[i]
  722. for j := range block.Rollup.Batches {
  723. batch := &block.Rollup.Batches[j]
  724. position := 0
  725. if batch.L1Batch {
  726. position = len(tc.Queues[*batch.Batch.ForgeL1TxsNum])
  727. }
  728. for k := range batch.L1CoordinatorTxs {
  729. tx := &batch.L1CoordinatorTxs[k]
  730. tx.Position = position
  731. position++
  732. nTx, err := common.NewL1Tx(tx)
  733. if err != nil {
  734. return err
  735. }
  736. *tx = *nTx
  737. }
  738. for k := range batch.L2Txs {
  739. tx := &batch.L2Txs[k]
  740. tx.Position = position
  741. position++
  742. tc.extra.nonces[tx.FromIdx]++
  743. tx.Nonce = tc.extra.nonces[tx.FromIdx]
  744. nTx, err := common.NewL2Tx(tx)
  745. if err != nil {
  746. return err
  747. }
  748. *tx = *nTx
  749. }
  750. }
  751. }
  752. // Fill ExitTree (only AccountIdx and Balance)
  753. for i := range blocks {
  754. block := &blocks[i]
  755. for j := range block.Rollup.Batches {
  756. batch := &block.Rollup.Batches[j]
  757. if batch.L1Batch {
  758. for _, _tx := range tc.Queues[*batch.Batch.ForgeL1TxsNum] {
  759. tx := _tx.L1Tx
  760. if tx.Type == common.TxTypeForceExit {
  761. batch.ExitTree =
  762. append(batch.ExitTree,
  763. common.ExitInfo{
  764. BatchNum: batch.Batch.BatchNum,
  765. AccountIdx: tx.FromIdx,
  766. Balance: tx.Amount,
  767. })
  768. }
  769. }
  770. }
  771. for k := range batch.L2Txs {
  772. tx := &batch.L2Txs[k]
  773. if tx.Type == common.TxTypeExit {
  774. batch.ExitTree = append(batch.ExitTree, common.ExitInfo{
  775. BatchNum: batch.Batch.BatchNum,
  776. AccountIdx: tx.FromIdx,
  777. Balance: tx.Amount,
  778. })
  779. }
  780. fee, err := common.CalcFeeAmount(tx.Amount, tx.Fee)
  781. if err != nil {
  782. return err
  783. }
  784. // Find the TokenID of the tx
  785. fromAcc, ok := tc.accountsByIdx[int(tx.FromIdx)]
  786. if !ok {
  787. return fmt.Errorf("L2tx.FromIdx idx: %v not found", tx.FromIdx)
  788. }
  789. // Find the idx of the CoordUser for the
  790. // TokenID, and if it exists, add the fee to
  791. // the collectedFees. Only consider the
  792. // coordinator account to receive fee if it was
  793. // created in this or a previous batch
  794. if acc, ok := tc.l1CreatedAccounts[idxTokenIDToString(cfg.CoordUser, fromAcc.TokenID)]; ok &&
  795. common.BatchNum(acc.BatchNum) <= batch.Batch.BatchNum {
  796. found := false
  797. for _, idx := range batch.Batch.FeeIdxsCoordinator {
  798. if idx == common.Idx(acc.Idx) {
  799. found = true
  800. break
  801. }
  802. }
  803. if !found {
  804. batch.Batch.FeeIdxsCoordinator = append(batch.Batch.FeeIdxsCoordinator,
  805. common.Idx(acc.Idx))
  806. batch.Batch.CollectedFees[fromAcc.TokenID] = big.NewInt(0)
  807. }
  808. collected := batch.Batch.CollectedFees[fromAcc.TokenID]
  809. collected.Add(collected, fee)
  810. }
  811. }
  812. }
  813. }
  814. return nil
  815. }