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.

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