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.

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