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.

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