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.

867 lines
28 KiB

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