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.

624 lines
21 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. }
  23. }
  24. func newBlock(blockNum int64) common.BlockData {
  25. return common.BlockData{
  26. Block: common.Block{
  27. EthBlockNum: blockNum,
  28. },
  29. Rollup: common.RollupData{
  30. L1UserTxs: []common.L1Tx{},
  31. },
  32. }
  33. }
  34. // Context contains the data of the test
  35. type Context struct {
  36. Instructions []instruction
  37. userNames []string
  38. Users map[string]*User
  39. LastRegisteredTokenID common.TokenID
  40. l1CreatedAccounts map[string]*Account
  41. // rollupConstMaxL1UserTx Maximum L1-user transactions allowed to be queued in a batch
  42. rollupConstMaxL1UserTx int
  43. idx int
  44. currBlock common.BlockData
  45. currBatch common.BatchData
  46. currBatchNum int
  47. Queues [][]L1Tx
  48. ToForgeNum int
  49. openToForge int
  50. currBatchTest struct {
  51. l1CoordinatorTxs []L1Tx
  52. l2Txs []L2Tx
  53. }
  54. blockNum int64
  55. }
  56. // NewContext returns a new Context
  57. func NewContext(rollupConstMaxL1UserTx int) *Context {
  58. currBatchNum := 1 // The protocol defines the first batchNum to be 1
  59. return &Context{
  60. Users: make(map[string]*User),
  61. l1CreatedAccounts: make(map[string]*Account),
  62. LastRegisteredTokenID: 0,
  63. rollupConstMaxL1UserTx: rollupConstMaxL1UserTx,
  64. idx: common.UserThreshold,
  65. // We use some placeholder values for StateRoot and ExitTree
  66. // because these values will never be nil
  67. currBlock: newBlock(2), //nolint:gomnd
  68. currBatch: newBatchData(currBatchNum),
  69. currBatchNum: currBatchNum,
  70. // start with 2 queues, one for toForge, and the other for openToForge
  71. Queues: make([][]L1Tx, 2),
  72. ToForgeNum: 0,
  73. openToForge: 1,
  74. //nolint:gomnd
  75. blockNum: 2, // rollup genesis blockNum
  76. }
  77. }
  78. // Account contains the data related to the account for a specific TokenID of a User
  79. type Account struct {
  80. Idx common.Idx
  81. Nonce common.Nonce
  82. }
  83. // User contains the data related to a testing user
  84. type User struct {
  85. BJJ *babyjub.PrivateKey
  86. Addr ethCommon.Address
  87. Accounts map[common.TokenID]*Account
  88. }
  89. // L1Tx is the data structure used internally for transaction test generation,
  90. // which contains a common.L1Tx data plus some intermediate data for the
  91. // transaction generation.
  92. type L1Tx struct {
  93. lineNum int
  94. fromIdxName string
  95. toIdxName string
  96. L1Tx common.L1Tx
  97. }
  98. // L2Tx is the data structure used internally for transaction test generation,
  99. // which contains a common.L2Tx data plus some intermediate data for the
  100. // transaction generation.
  101. type L2Tx struct {
  102. lineNum int
  103. fromIdxName string
  104. toIdxName string
  105. tokenID common.TokenID
  106. L2Tx common.L2Tx
  107. }
  108. // GenerateBlocks returns an array of BlockData for a given set. It uses the
  109. // users (keys & nonces) of the Context.
  110. func (tc *Context) GenerateBlocks(set string) ([]common.BlockData, error) {
  111. parser := newParser(strings.NewReader(set))
  112. parsedSet, err := parser.parse()
  113. if err != nil {
  114. return nil, err
  115. }
  116. if parsedSet.typ != setTypeBlockchain {
  117. return nil, fmt.Errorf("Expected set type: %s, found: %s", setTypeBlockchain, parsedSet.typ)
  118. }
  119. tc.Instructions = parsedSet.instructions
  120. tc.userNames = parsedSet.users
  121. tc.generateKeys(tc.userNames)
  122. var blocks []common.BlockData
  123. for _, inst := range parsedSet.instructions {
  124. switch inst.typ {
  125. case txTypeCreateAccountDepositCoordinator: // tx source: L1CoordinatorTx
  126. if err := tc.checkIfTokenIsRegistered(inst); err != nil {
  127. log.Error(err)
  128. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  129. }
  130. tx := common.L1Tx{
  131. FromEthAddr: tc.Users[inst.from].Addr,
  132. FromBJJ: tc.Users[inst.from].BJJ.Public(),
  133. TokenID: inst.tokenID,
  134. Amount: big.NewInt(0),
  135. LoadAmount: big.NewInt(int64(inst.loadAmount)),
  136. Type: common.TxTypeCreateAccountDeposit, // as txTypeCreateAccountDepositCoordinator is not valid oustide Til package
  137. }
  138. testTx := L1Tx{
  139. lineNum: inst.lineNum,
  140. fromIdxName: inst.from,
  141. L1Tx: tx,
  142. }
  143. tc.currBatchTest.l1CoordinatorTxs = append(tc.currBatchTest.l1CoordinatorTxs, testTx)
  144. case common.TxTypeCreateAccountDeposit, common.TxTypeCreateAccountDepositTransfer: // tx source: L1UserTx
  145. if err := tc.checkIfTokenIsRegistered(inst); err != nil {
  146. log.Error(err)
  147. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  148. }
  149. tx := common.L1Tx{
  150. FromEthAddr: tc.Users[inst.from].Addr,
  151. FromBJJ: tc.Users[inst.from].BJJ.Public(),
  152. TokenID: inst.tokenID,
  153. Amount: big.NewInt(0),
  154. LoadAmount: big.NewInt(int64(inst.loadAmount)),
  155. Type: inst.typ,
  156. }
  157. if inst.typ == common.TxTypeCreateAccountDepositTransfer {
  158. tx.Amount = big.NewInt(int64(inst.amount))
  159. }
  160. testTx := L1Tx{
  161. lineNum: inst.lineNum,
  162. fromIdxName: inst.from,
  163. toIdxName: inst.to,
  164. L1Tx: tx,
  165. }
  166. if err := tc.addToL1Queue(testTx); err != nil {
  167. return nil, err
  168. }
  169. case common.TxTypeDeposit, common.TxTypeDepositTransfer: // tx source: L1UserTx
  170. if err := tc.checkIfTokenIsRegistered(inst); err != nil {
  171. log.Error(err)
  172. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  173. }
  174. if err := tc.checkIfAccountExists(inst.from, inst); err != nil {
  175. log.Error(err)
  176. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  177. }
  178. tx := common.L1Tx{
  179. TokenID: inst.tokenID,
  180. Amount: big.NewInt(0),
  181. LoadAmount: big.NewInt(int64(inst.loadAmount)),
  182. Type: inst.typ,
  183. }
  184. if inst.typ == common.TxTypeDepositTransfer {
  185. tx.Amount = big.NewInt(int64(inst.amount))
  186. }
  187. testTx := L1Tx{
  188. lineNum: inst.lineNum,
  189. fromIdxName: inst.from,
  190. toIdxName: inst.to,
  191. L1Tx: tx,
  192. }
  193. if err := tc.addToL1Queue(testTx); err != nil {
  194. return nil, err
  195. }
  196. case common.TxTypeTransfer: // L2Tx
  197. if err := tc.checkIfTokenIsRegistered(inst); err != nil {
  198. log.Error(err)
  199. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  200. }
  201. tx := common.L2Tx{
  202. Amount: big.NewInt(int64(inst.amount)),
  203. Fee: common.FeeSelector(inst.fee),
  204. Type: common.TxTypeTransfer,
  205. EthBlockNum: tc.blockNum,
  206. }
  207. tx.BatchNum = common.BatchNum(tc.currBatchNum) // when converted to PoolL2Tx BatchNum parameter is lost
  208. testTx := L2Tx{
  209. lineNum: inst.lineNum,
  210. fromIdxName: inst.from,
  211. toIdxName: inst.to,
  212. tokenID: inst.tokenID,
  213. L2Tx: tx,
  214. }
  215. tc.currBatchTest.l2Txs = append(tc.currBatchTest.l2Txs, testTx)
  216. case common.TxTypeForceTransfer: // tx source: L1UserTx
  217. if err := tc.checkIfTokenIsRegistered(inst); err != nil {
  218. log.Error(err)
  219. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  220. }
  221. tx := common.L1Tx{
  222. TokenID: inst.tokenID,
  223. Amount: big.NewInt(int64(inst.amount)),
  224. LoadAmount: big.NewInt(0),
  225. Type: common.TxTypeForceTransfer,
  226. }
  227. testTx := L1Tx{
  228. lineNum: inst.lineNum,
  229. fromIdxName: inst.from,
  230. toIdxName: inst.to,
  231. L1Tx: tx,
  232. }
  233. if err := tc.addToL1Queue(testTx); err != nil {
  234. return nil, err
  235. }
  236. case common.TxTypeExit: // tx source: L2Tx
  237. if err := tc.checkIfTokenIsRegistered(inst); err != nil {
  238. log.Error(err)
  239. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  240. }
  241. tx := common.L2Tx{
  242. ToIdx: common.Idx(1), // as is an Exit
  243. Fee: common.FeeSelector(inst.fee),
  244. Amount: big.NewInt(int64(inst.amount)),
  245. Type: common.TxTypeExit,
  246. EthBlockNum: tc.blockNum,
  247. }
  248. tx.BatchNum = common.BatchNum(tc.currBatchNum) // when converted to PoolL2Tx BatchNum parameter is lost
  249. testTx := L2Tx{
  250. lineNum: inst.lineNum,
  251. fromIdxName: inst.from,
  252. toIdxName: inst.to,
  253. tokenID: inst.tokenID,
  254. L2Tx: tx,
  255. }
  256. tc.currBatchTest.l2Txs = append(tc.currBatchTest.l2Txs, testTx)
  257. case common.TxTypeForceExit: // tx source: L1UserTx
  258. if err := tc.checkIfTokenIsRegistered(inst); err != nil {
  259. log.Error(err)
  260. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  261. }
  262. tx := common.L1Tx{
  263. ToIdx: common.Idx(1), // as is an Exit
  264. TokenID: inst.tokenID,
  265. Amount: big.NewInt(int64(inst.amount)),
  266. LoadAmount: big.NewInt(0),
  267. Type: common.TxTypeForceExit,
  268. }
  269. testTx := L1Tx{
  270. lineNum: inst.lineNum,
  271. fromIdxName: inst.from,
  272. toIdxName: inst.to,
  273. L1Tx: tx,
  274. }
  275. if err := tc.addToL1Queue(testTx); err != nil {
  276. return nil, err
  277. }
  278. case typeNewBatch:
  279. if err = tc.calculateIdxForL1Txs(true, tc.currBatchTest.l1CoordinatorTxs); err != nil {
  280. return nil, err
  281. }
  282. if err = tc.setIdxs(); err != nil {
  283. log.Error(err)
  284. return nil, err
  285. }
  286. case typeNewBatchL1:
  287. // for each L1UserTx of the Queues[ToForgeNum], calculate the Idx
  288. if err = tc.calculateIdxForL1Txs(false, tc.Queues[tc.ToForgeNum]); err != nil {
  289. return nil, err
  290. }
  291. if err = tc.calculateIdxForL1Txs(true, tc.currBatchTest.l1CoordinatorTxs); err != nil {
  292. return nil, err
  293. }
  294. tc.currBatch.L1Batch = true
  295. if err = tc.setIdxs(); err != nil {
  296. log.Error(err)
  297. return nil, err
  298. }
  299. toForgeL1TxsNum := int64(tc.openToForge)
  300. tc.currBatch.Batch.ForgeL1TxsNum = &toForgeL1TxsNum
  301. // advance batch
  302. tc.ToForgeNum++
  303. if tc.ToForgeNum == tc.openToForge {
  304. tc.openToForge++
  305. newQueue := []L1Tx{}
  306. tc.Queues = append(tc.Queues, newQueue)
  307. }
  308. case typeNewBlock:
  309. blocks = append(blocks, tc.currBlock)
  310. tc.blockNum++
  311. tc.currBlock = newBlock(tc.blockNum)
  312. case typeAddToken:
  313. newToken := common.Token{
  314. EthAddr: ethCommon.BigToAddress(big.NewInt(int64(inst.tokenID * 100))), //nolint:gomnd
  315. // Name: fmt.Sprintf("Token %d", inst.tokenID),
  316. // Symbol: fmt.Sprintf("TK%d", inst.tokenID),
  317. // Decimals: 18,
  318. TokenID: inst.tokenID,
  319. EthBlockNum: tc.blockNum,
  320. }
  321. if inst.tokenID != tc.LastRegisteredTokenID+1 {
  322. return nil, fmt.Errorf("Line %d: AddToken TokenID should be sequential, expected TokenID: %d, defined TokenID: %d", inst.lineNum, tc.LastRegisteredTokenID+1, inst.tokenID)
  323. }
  324. tc.LastRegisteredTokenID++
  325. tc.currBlock.Rollup.AddedTokens = append(tc.currBlock.Rollup.AddedTokens, newToken)
  326. default:
  327. return nil, fmt.Errorf("Line %d: Unexpected type: %s", inst.lineNum, inst.typ)
  328. }
  329. }
  330. return blocks, nil
  331. }
  332. // calculateIdxsForL1Txs calculates new Idx for new created accounts. If
  333. // 'isCoordinatorTxs==true', adds the tx to tc.currBatch.L1CoordinatorTxs.
  334. func (tc *Context) calculateIdxForL1Txs(isCoordinatorTxs bool, txs []L1Tx) error {
  335. // for each batch.L1CoordinatorTxs of the Queues[ToForgeNum], calculate the Idx
  336. for i := 0; i < len(txs); i++ {
  337. tx := txs[i]
  338. if tx.L1Tx.Type == common.TxTypeCreateAccountDeposit || tx.L1Tx.Type == common.TxTypeCreateAccountDepositTransfer {
  339. if tc.Users[tx.fromIdxName].Accounts[tx.L1Tx.TokenID] != nil { // if account already exists, return error
  340. 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)
  341. }
  342. tc.Users[tx.fromIdxName].Accounts[tx.L1Tx.TokenID] = &Account{
  343. Idx: common.Idx(tc.idx),
  344. Nonce: common.Nonce(0),
  345. }
  346. tc.l1CreatedAccounts[idxTokenIDToString(tx.fromIdxName, tx.L1Tx.TokenID)] = tc.Users[tx.fromIdxName].Accounts[tx.L1Tx.TokenID]
  347. tc.idx++
  348. }
  349. if isCoordinatorTxs {
  350. tc.currBatch.L1CoordinatorTxs = append(tc.currBatch.L1CoordinatorTxs, tx.L1Tx)
  351. }
  352. }
  353. return nil
  354. }
  355. // setIdxs sets the Idxs to the transactions of the tc.currBatch
  356. func (tc *Context) setIdxs() error {
  357. // once Idxs are calculated, update transactions to use the new Idxs
  358. for i := 0; i < len(tc.currBatchTest.l2Txs); i++ {
  359. testTx := &tc.currBatchTest.l2Txs[i]
  360. if tc.Users[testTx.fromIdxName].Accounts[testTx.tokenID] == nil {
  361. 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)
  362. }
  363. if testTx.L2Tx.Type == common.TxTypeTransfer {
  364. if _, ok := tc.l1CreatedAccounts[idxTokenIDToString(testTx.toIdxName, testTx.tokenID)]; !ok {
  365. 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)
  366. }
  367. }
  368. tc.Users[testTx.fromIdxName].Accounts[testTx.tokenID].Nonce++
  369. // next line is commented to avoid Blockchain L2Txs to have
  370. // Nonce different from 0, as from Blockchain those
  371. // transactions will come without Nonce
  372. // testTx.L2Tx.Nonce = tc.Users[testTx.fromIdxName].Accounts[testTx.tokenID].Nonce
  373. // set real Idx
  374. testTx.L2Tx.FromIdx = tc.Users[testTx.fromIdxName].Accounts[testTx.tokenID].Idx
  375. if testTx.L2Tx.Type == common.TxTypeTransfer {
  376. testTx.L2Tx.ToIdx = tc.Users[testTx.toIdxName].Accounts[testTx.tokenID].Idx
  377. }
  378. // in case Type==Exit, ToIdx=1, already set at the
  379. // GenerateBlocks main switch inside TxTypeExit case
  380. nTx, err := common.NewL2Tx(&testTx.L2Tx)
  381. if err != nil {
  382. return fmt.Errorf("Line %d: %s", testTx.lineNum, err.Error())
  383. }
  384. testTx.L2Tx = *nTx
  385. tc.currBatch.L2Txs = append(tc.currBatch.L2Txs, testTx.L2Tx)
  386. }
  387. tc.currBatch.Batch.LastIdx = int64(tc.idx - 1) // `-1` because tc.idx is the next available idx
  388. tc.currBlock.Rollup.Batches = append(tc.currBlock.Rollup.Batches, tc.currBatch)
  389. tc.currBatchNum++
  390. tc.currBatch = newBatchData(tc.currBatchNum)
  391. tc.currBatchTest.l1CoordinatorTxs = nil
  392. tc.currBatchTest.l2Txs = nil
  393. return nil
  394. }
  395. // addToL1Queue adds the L1Tx into the queue that is open and has space
  396. func (tc *Context) addToL1Queue(tx L1Tx) error {
  397. if len(tc.Queues[tc.openToForge]) >= tc.rollupConstMaxL1UserTx {
  398. // if current OpenToForge queue reached its Max, move into a
  399. // new queue
  400. tc.openToForge++
  401. newQueue := []L1Tx{}
  402. tc.Queues = append(tc.Queues, newQueue)
  403. }
  404. // Fill L1UserTx specific parameters
  405. tx.L1Tx.UserOrigin = true
  406. toForgeL1TxsNum := int64(tc.openToForge)
  407. tx.L1Tx.ToForgeL1TxsNum = &toForgeL1TxsNum
  408. tx.L1Tx.EthBlockNum = tc.blockNum
  409. tx.L1Tx.Position = len(tc.Queues[tc.openToForge])
  410. // When an L1UserTx is generated, all idxs must be available (except when idx == 0 or idx == 1)
  411. if tx.L1Tx.Type != common.TxTypeCreateAccountDeposit && tx.L1Tx.Type != common.TxTypeCreateAccountDepositTransfer {
  412. tx.L1Tx.FromIdx = tc.Users[tx.fromIdxName].Accounts[tx.L1Tx.TokenID].Idx
  413. }
  414. tx.L1Tx.FromEthAddr = tc.Users[tx.fromIdxName].Addr
  415. tx.L1Tx.FromBJJ = tc.Users[tx.fromIdxName].BJJ.Public()
  416. if tx.toIdxName == "" {
  417. tx.L1Tx.ToIdx = common.Idx(0)
  418. } else {
  419. account, ok := tc.Users[tx.toIdxName].Accounts[tx.L1Tx.TokenID]
  420. if !ok {
  421. return fmt.Errorf("Line %d: Transfer to User: %s, for TokenID: %d, "+
  422. "while account not created yet", tx.lineNum, tx.toIdxName, tx.L1Tx.TokenID)
  423. }
  424. tx.L1Tx.ToIdx = account.Idx
  425. }
  426. if tx.L1Tx.Type == common.TxTypeForceExit {
  427. tx.L1Tx.ToIdx = common.Idx(1)
  428. }
  429. nTx, err := common.NewL1Tx(&tx.L1Tx)
  430. if err != nil {
  431. return fmt.Errorf("Line %d: %s", tx.lineNum, err.Error())
  432. }
  433. tx.L1Tx = *nTx
  434. tc.Queues[tc.openToForge] = append(tc.Queues[tc.openToForge], tx)
  435. tc.currBlock.Rollup.L1UserTxs = append(tc.currBlock.Rollup.L1UserTxs, tx.L1Tx)
  436. return nil
  437. }
  438. func (tc *Context) checkIfAccountExists(tf string, inst instruction) error {
  439. if tc.Users[tf].Accounts[inst.tokenID] == nil {
  440. return fmt.Errorf("%s at User: %s, for TokenID: %d, while account not created yet", inst.typ, tf, inst.tokenID)
  441. }
  442. return nil
  443. }
  444. func (tc *Context) checkIfTokenIsRegistered(inst instruction) error {
  445. if inst.tokenID > tc.LastRegisteredTokenID {
  446. return fmt.Errorf("Can not process %s: TokenID %d not registered, last registered TokenID: %d", inst.typ, inst.tokenID, tc.LastRegisteredTokenID)
  447. }
  448. return nil
  449. }
  450. // GeneratePoolL2Txs returns an array of common.PoolL2Tx from a given set. It
  451. // uses the users (keys) of the Context.
  452. func (tc *Context) GeneratePoolL2Txs(set string) ([]common.PoolL2Tx, error) {
  453. parser := newParser(strings.NewReader(set))
  454. parsedSet, err := parser.parse()
  455. if err != nil {
  456. return nil, err
  457. }
  458. if parsedSet.typ != setTypePoolL2 {
  459. return nil, fmt.Errorf("Expected set type: %s, found: %s", setTypePoolL2, parsedSet.typ)
  460. }
  461. tc.Instructions = parsedSet.instructions
  462. tc.userNames = parsedSet.users
  463. tc.generateKeys(tc.userNames)
  464. txs := []common.PoolL2Tx{}
  465. for _, inst := range tc.Instructions {
  466. switch inst.typ {
  467. case common.TxTypeTransfer, common.TxTypeTransferToEthAddr, common.TxTypeTransferToBJJ:
  468. if err := tc.checkIfAccountExists(inst.from, inst); err != nil {
  469. log.Error(err)
  470. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  471. }
  472. if inst.typ == common.TxTypeTransfer {
  473. // if TxTypeTransfer, need to exist the ToIdx account
  474. if err := tc.checkIfAccountExists(inst.to, inst); err != nil {
  475. log.Error(err)
  476. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  477. }
  478. }
  479. tc.Users[inst.from].Accounts[inst.tokenID].Nonce++
  480. // if account of receiver does not exist, don't use
  481. // ToIdx, and use only ToEthAddr & ToBJJ
  482. tx := common.PoolL2Tx{
  483. FromIdx: tc.Users[inst.from].Accounts[inst.tokenID].Idx,
  484. TokenID: inst.tokenID,
  485. Amount: big.NewInt(int64(inst.amount)),
  486. Fee: common.FeeSelector(inst.fee),
  487. Nonce: tc.Users[inst.from].Accounts[inst.tokenID].Nonce,
  488. State: common.PoolL2TxStatePending,
  489. Timestamp: time.Now(),
  490. RqToEthAddr: common.EmptyAddr,
  491. RqToBJJ: nil,
  492. Type: inst.typ,
  493. }
  494. if tx.Type == common.TxTypeTransfer {
  495. tx.ToIdx = tc.Users[inst.to].Accounts[inst.tokenID].Idx
  496. tx.ToEthAddr = tc.Users[inst.to].Addr
  497. tx.ToBJJ = tc.Users[inst.to].BJJ.Public()
  498. } else if tx.Type == common.TxTypeTransferToEthAddr {
  499. tx.ToIdx = common.Idx(0)
  500. tx.ToEthAddr = tc.Users[inst.to].Addr
  501. } else if tx.Type == common.TxTypeTransferToBJJ {
  502. tx.ToIdx = common.Idx(0)
  503. tx.ToEthAddr = common.FFAddr
  504. tx.ToBJJ = tc.Users[inst.to].BJJ.Public()
  505. }
  506. nTx, err := common.NewPoolL2Tx(&tx)
  507. if err != nil {
  508. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  509. }
  510. tx = *nTx
  511. // perform signature and set it to tx.Signature
  512. toSign, err := tx.HashToSign()
  513. if err != nil {
  514. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  515. }
  516. sig := tc.Users[inst.from].BJJ.SignPoseidon(toSign)
  517. tx.Signature = sig.Compress()
  518. txs = append(txs, tx)
  519. case common.TxTypeExit:
  520. tc.Users[inst.from].Accounts[inst.tokenID].Nonce++
  521. tx := common.PoolL2Tx{
  522. FromIdx: tc.Users[inst.from].Accounts[inst.tokenID].Idx,
  523. ToIdx: common.Idx(1), // as is an Exit
  524. Fee: common.FeeSelector(inst.fee),
  525. TokenID: inst.tokenID,
  526. Amount: big.NewInt(int64(inst.amount)),
  527. Nonce: tc.Users[inst.from].Accounts[inst.tokenID].Nonce,
  528. Type: common.TxTypeExit,
  529. }
  530. nTx, err := common.NewPoolL2Tx(&tx)
  531. if err != nil {
  532. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  533. }
  534. tx = *nTx
  535. // perform signature and set it to tx.Signature
  536. toSign, err := tx.HashToSign()
  537. if err != nil {
  538. return nil, fmt.Errorf("Line %d: %s", inst.lineNum, err.Error())
  539. }
  540. sig := tc.Users[inst.from].BJJ.SignPoseidon(toSign)
  541. tx.Signature = sig.Compress()
  542. txs = append(txs, tx)
  543. default:
  544. return nil, fmt.Errorf("Line %d: instruction type unrecognized: %s", inst.lineNum, inst.typ)
  545. }
  546. }
  547. return txs, nil
  548. }
  549. // generateKeys generates BabyJubJub & Address keys for the given list of user
  550. // names in a deterministic way. This means, that for the same given
  551. // 'userNames' in a certain order, the keys will be always the same.
  552. func (tc *Context) generateKeys(userNames []string) {
  553. for i := 1; i < len(userNames)+1; i++ {
  554. if _, ok := tc.Users[userNames[i-1]]; ok {
  555. // account already created
  556. continue
  557. }
  558. // babyjubjub key
  559. var sk babyjub.PrivateKey
  560. copy(sk[:], []byte(strconv.Itoa(i))) // only for testing
  561. // eth address
  562. var key ecdsa.PrivateKey
  563. key.D = big.NewInt(int64(i)) // only for testing
  564. key.PublicKey.X, key.PublicKey.Y = ethCrypto.S256().ScalarBaseMult(key.D.Bytes())
  565. key.Curve = ethCrypto.S256()
  566. addr := ethCrypto.PubkeyToAddress(key.PublicKey)
  567. u := User{
  568. BJJ: &sk,
  569. Addr: addr,
  570. Accounts: make(map[common.TokenID]*Account),
  571. }
  572. tc.Users[userNames[i-1]] = &u
  573. }
  574. }
  575. // L1TxsToCommonL1Txs converts an array of []til.L1Tx to []common.L1Tx
  576. func L1TxsToCommonL1Txs(l1 []L1Tx) []common.L1Tx {
  577. var r []common.L1Tx
  578. for i := 0; i < len(l1); i++ {
  579. r = append(r, l1[i].L1Tx)
  580. }
  581. return r
  582. }