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.

856 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(int64(inst.loadAmount)),
  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. Type: common.TxTypeExit,
  556. }
  557. nTx, err := common.NewPoolL2Tx(&tx)
  558. if err != nil {
  559. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  560. }
  561. tx = *nTx
  562. // perform signature and set it to tx.Signature
  563. toSign, err := tx.HashToSign()
  564. if err != nil {
  565. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  566. }
  567. sig := tc.Users[inst.from].BJJ.SignPoseidon(toSign)
  568. tx.Signature = sig.Compress()
  569. txs = append(txs, tx)
  570. default:
  571. return nil, fmt.Errorf("Line %d: instruction type unrecognized: %s", inst.lineNum, inst.typ)
  572. }
  573. }
  574. return txs, nil
  575. }
  576. // generateKeys generates BabyJubJub & Address keys for the given list of user
  577. // names in a deterministic way. This means, that for the same given
  578. // 'userNames' in a certain order, the keys will be always the same.
  579. func (tc *Context) generateKeys(userNames []string) {
  580. for i := 1; i < len(userNames)+1; i++ {
  581. if _, ok := tc.Users[userNames[i-1]]; ok {
  582. // account already created
  583. continue
  584. }
  585. // babyjubjub key
  586. var sk babyjub.PrivateKey
  587. copy(sk[:], []byte(strconv.Itoa(i))) // only for testing
  588. // eth address
  589. var key ecdsa.PrivateKey
  590. key.D = big.NewInt(int64(i)) // only for testing
  591. key.PublicKey.X, key.PublicKey.Y = ethCrypto.S256().ScalarBaseMult(key.D.Bytes())
  592. key.Curve = ethCrypto.S256()
  593. addr := ethCrypto.PubkeyToAddress(key.PublicKey)
  594. u := User{
  595. Name: userNames[i-1],
  596. BJJ: &sk,
  597. Addr: addr,
  598. Accounts: make(map[common.TokenID]*Account),
  599. }
  600. tc.Users[userNames[i-1]] = &u
  601. }
  602. }
  603. // L1TxsToCommonL1Txs converts an array of []til.L1Tx to []common.L1Tx
  604. func L1TxsToCommonL1Txs(l1 []L1Tx) []common.L1Tx {
  605. var r []common.L1Tx
  606. for i := 0; i < len(l1); i++ {
  607. r = append(r, l1[i].L1Tx)
  608. }
  609. return r
  610. }
  611. // ConfigExtra is the configuration used in FillBlocksExtra to extend the
  612. // blocks returned by til.
  613. type ConfigExtra struct {
  614. // Address to set as forger for each batch
  615. BootCoordAddr ethCommon.Address
  616. // Coordinator user name used to select the corresponding accounts to
  617. // collect coordinator fees
  618. CoordUser string
  619. }
  620. // FillBlocksExtra fills extra fields not generated by til in each block, so
  621. // that the blockData is closer to what the HistoryDB stores. The filled fields are:
  622. // - blocks[].Rollup.L1UserTxs[].BatchNum
  623. // - blocks[].Rollup.Batch.EthBlockNum
  624. // - blocks[].Rollup.Batch.ForgerAddr
  625. // - blocks[].Rollup.Batch.ForgeL1TxsNum
  626. // - blocks[].Rollup.Batch.L1CoordinatorTxs[].TxID
  627. // - blocks[].Rollup.Batch.L1CoordinatorTxs[].BatchNum
  628. // - blocks[].Rollup.Batch.L1CoordinatorTxs[].EthBlockNum
  629. // - blocks[].Rollup.Batch.L1CoordinatorTxs[].Position
  630. // - blocks[].Rollup.Batch.L2Txs[].TxID
  631. // - blocks[].Rollup.Batch.L2Txs[].Position
  632. // - blocks[].Rollup.Batch.L2Txs[].Nonce
  633. // - blocks[].Rollup.Batch.ExitTree
  634. // - blocks[].Rollup.Batch.CreatedAccounts
  635. // - blocks[].Rollup.Batch.FeeIdxCoordinator
  636. // - blocks[].Rollup.Batch.CollectedFees
  637. func (tc *Context) FillBlocksExtra(blocks []common.BlockData, cfg *ConfigExtra) error {
  638. // Fill extra fields not generated by til in til block
  639. for i := range blocks {
  640. block := &blocks[i]
  641. for j := range block.Rollup.Batches {
  642. batch := &block.Rollup.Batches[j]
  643. if batch.L1Batch {
  644. // Set BatchNum for forged L1UserTxs to til blocks
  645. bn := batch.Batch.BatchNum
  646. for k := range blocks {
  647. block := &blocks[k]
  648. for l := range block.Rollup.L1UserTxs {
  649. tx := &block.Rollup.L1UserTxs[l]
  650. if *tx.ToForgeL1TxsNum == tc.extra.openToForge {
  651. tx.BatchNum = &bn
  652. }
  653. }
  654. }
  655. tc.extra.openToForge++
  656. }
  657. batch.Batch.EthBlockNum = block.Block.EthBlockNum
  658. // til doesn't fill the batch forger addr
  659. batch.Batch.ForgerAddr = cfg.BootCoordAddr
  660. if batch.L1Batch {
  661. toForgeL1TxsNumCpy := tc.extra.toForgeL1TxsNum
  662. // til doesn't fill the ForgeL1TxsNum
  663. batch.Batch.ForgeL1TxsNum = &toForgeL1TxsNumCpy
  664. tc.extra.toForgeL1TxsNum++
  665. }
  666. batchNum := batch.Batch.BatchNum
  667. for k := range batch.L1CoordinatorTxs {
  668. tx := &batch.L1CoordinatorTxs[k]
  669. tx.BatchNum = &batchNum
  670. tx.EthBlockNum = batch.Batch.EthBlockNum
  671. }
  672. }
  673. }
  674. // Fill CreatedAccounts
  675. for i := range blocks {
  676. block := &blocks[i]
  677. for j := range block.Rollup.Batches {
  678. batch := &block.Rollup.Batches[j]
  679. l1Txs := []common.L1Tx{}
  680. if batch.L1Batch {
  681. for _, tx := range tc.Queues[*batch.Batch.ForgeL1TxsNum] {
  682. l1Txs = append(l1Txs, tx.L1Tx)
  683. }
  684. }
  685. l1Txs = append(l1Txs, batch.L1CoordinatorTxs...)
  686. for k := range l1Txs {
  687. tx := &l1Txs[k]
  688. if tx.Type == common.TxTypeCreateAccountDeposit ||
  689. tx.Type == common.TxTypeCreateAccountDepositTransfer {
  690. user, ok := tc.usersByIdx[tc.extra.idx]
  691. if !ok {
  692. return fmt.Errorf("Created account with idx: %v not found", tc.extra.idx)
  693. }
  694. batch.CreatedAccounts = append(batch.CreatedAccounts,
  695. common.Account{
  696. Idx: common.Idx(tc.extra.idx),
  697. TokenID: tx.TokenID,
  698. BatchNum: batch.Batch.BatchNum,
  699. PublicKey: user.BJJ.Public(),
  700. EthAddr: user.Addr,
  701. Nonce: 0,
  702. Balance: big.NewInt(0),
  703. })
  704. tc.extra.idx++
  705. }
  706. }
  707. }
  708. }
  709. // Fill expected positions in L1CoordinatorTxs and L2Txs
  710. for i := range blocks {
  711. block := &blocks[i]
  712. for j := range block.Rollup.Batches {
  713. batch := &block.Rollup.Batches[j]
  714. position := 0
  715. if batch.L1Batch {
  716. position = len(tc.Queues[*batch.Batch.ForgeL1TxsNum])
  717. }
  718. for k := range batch.L1CoordinatorTxs {
  719. tx := &batch.L1CoordinatorTxs[k]
  720. tx.Position = position
  721. position++
  722. nTx, err := common.NewL1Tx(tx)
  723. if err != nil {
  724. return err
  725. }
  726. *tx = *nTx
  727. }
  728. for k := range batch.L2Txs {
  729. tx := &batch.L2Txs[k]
  730. tx.Position = position
  731. position++
  732. tc.extra.nonces[tx.FromIdx]++
  733. tx.Nonce = tc.extra.nonces[tx.FromIdx]
  734. nTx, err := common.NewL2Tx(tx)
  735. if err != nil {
  736. return err
  737. }
  738. *tx = *nTx
  739. }
  740. }
  741. }
  742. // Fill ExitTree (only AccountIdx and Balance)
  743. for i := range blocks {
  744. block := &blocks[i]
  745. for j := range block.Rollup.Batches {
  746. batch := &block.Rollup.Batches[j]
  747. if batch.L1Batch {
  748. for _, _tx := range tc.Queues[*batch.Batch.ForgeL1TxsNum] {
  749. tx := _tx.L1Tx
  750. if tx.Type == common.TxTypeForceExit {
  751. batch.ExitTree =
  752. append(batch.ExitTree,
  753. common.ExitInfo{
  754. AccountIdx: tx.FromIdx,
  755. Balance: tx.Amount,
  756. })
  757. }
  758. }
  759. }
  760. for k := range batch.L2Txs {
  761. tx := &batch.L2Txs[k]
  762. if tx.Type == common.TxTypeExit {
  763. batch.ExitTree = append(batch.ExitTree, common.ExitInfo{
  764. AccountIdx: tx.FromIdx,
  765. Balance: tx.Amount,
  766. })
  767. }
  768. fee, err := common.CalcFeeAmount(tx.Amount, tx.Fee)
  769. if err != nil {
  770. return err
  771. }
  772. // Find the TokenID of the tx
  773. fromAcc, ok := tc.accountsByIdx[int(tx.FromIdx)]
  774. if !ok {
  775. return fmt.Errorf("L2tx.FromIdx idx: %v not found", tx.FromIdx)
  776. }
  777. // Find the idx of the CoordUser for the
  778. // TokenID, and if it exists, add the fee to
  779. // the collectedFees. Only consider the
  780. // coordinator account to receive fee if it was
  781. // created in this or a previous batch
  782. if acc, ok := tc.l1CreatedAccounts[idxTokenIDToString(cfg.CoordUser, fromAcc.TokenID)]; ok &&
  783. common.BatchNum(acc.BatchNum) <= batch.Batch.BatchNum {
  784. found := false
  785. for _, idx := range batch.Batch.FeeIdxsCoordinator {
  786. if idx == common.Idx(acc.Idx) {
  787. found = true
  788. break
  789. }
  790. }
  791. if !found {
  792. batch.Batch.FeeIdxsCoordinator = append(batch.Batch.FeeIdxsCoordinator,
  793. common.Idx(acc.Idx))
  794. batch.Batch.CollectedFees[fromAcc.TokenID] = big.NewInt(0)
  795. }
  796. collected := batch.Batch.CollectedFees[fromAcc.TokenID]
  797. collected.Add(collected, fee)
  798. }
  799. }
  800. }
  801. }
  802. return nil
  803. }