import { should } from '../..//setup' ; import { BigNumber , DefaultSignatureProvider , ONE , serializeObject , SignatureProvider , } from '@pigi/core-utils' ; import * as assert from 'assert' ; import { Aggregator , BlockTransactionCommitment , HistoryProof , StateManager , StateQuery , StateQueryResult , StateUpdate , Transaction , TransactionResult , BlockManager , } from '../../../src' ; import { DefaultAggregator } from '../../../src/app/aggregator' ; import { TestUtils } from '../test-utils' ; import { transactionsEqual } from '../../../src/app/utils' ; /*******************
 * Mocks & Helpers *
 *******************/ class DummyBlockManager implements BlockManager { private nextBlockNumber : BigNumber ; private readonly stateUpdates : StateUpdate [ ] ; constructor ( ) { this . nextBlockNumber = ONE ; this . stateUpdates = [ ] ; } public async addPendingStateUpdate ( stateUpdate ) { this . stateUpdates . push ( stateUpdate ) ; } public async getNextBlockNumber ( ) { return this . nextBlockNumber ; } public async getPendingStateUpdates ( ) { return this . stateUpdates ; } public async submitNextBlock ( ) { this . stateUpdates . length = 0 ; this . nextBlockNumber = this . nextBlockNumber . add ( ONE ) ; } } class DummyStateManager implements StateManager { private throwOnExecute : boolean = false ; private executeTransactionResults : TransactionResult [ ] ; public setExecuteTransactionResults ( transactionResults ) { this . executeTransactionResults = transactionResults ; } public throwOnExecuteTransaction ( ) { this . throwOnExecute = true ; } public async executeTransaction ( transaction , inBlock , witness ) { if ( this . throwOnExecute ) { this . throwOnExecute = false ; throw Error ( 'I was configured to throw' ) ; } return this . executeTransactionResults . shift ( ) ; } public async ingestHistoryProof ( historyProof ) { return undefined ; } public async queryState ( query ) { return undefined ; } } /*********
 * TESTS *
 *********/ describe ( 'DefaultAggregator' , ( ) => { let blockManager ; let stateManager ; let aggregator ; let aggregatorAddress ; let signatureProvider ; beforeEach ( async ( ) => { blockManager = new DummyBlockManager ( ) ; stateManager = new DummyStateManager ( ) ; signatureProvider = new DefaultSignatureProvider ( ) ; aggregatorAddress = await signatureProvider . getAddress ( ) ; aggregator = new DefaultAggregator ( stateManager , blockManager , aggregatorAddress , signatureProvider ) ; } ) ; describe ( 'ingestTransaction' , ( ) => { it ( 'Ingests transaction correctly' , async ( ) => { const numTransactions = 5 ; const transactionResults = TestUtils . generateNSequentialTransactionResults ( numTransactions ) ; stateManager . setExecuteTransactionResults ( [ ... transactionResults ] ) ; const transactions = [ ] ; transactionResults . forEach ( ( result ) => { transactions . push ( { depositAddress : '' , range : result . validRanges [ 0 ] , body : { } , } ) ; } ) ; for ( let i = 0 ; i < numTransactions ; i ++ ) { const txCommitment = await aggregator . ingestTransaction ( transactions [ i ] ) ; assert ( transactionsEqual ( txCommitment . blockTransaction . transaction , transactions [ i ] ) , 'Resulting BlockTransactionCommitment does not match passed in Transaction.' ) ; const serializedCommitment = serializeObject ( txCommitment . blockTransaction ) ; const signature = await signatureProvider . sign ( serializedCommitment ) ; assert ( txCommitment . witness === signature , 'commitment signature should match' ) ; } const stateUpdates = await blockManager . getPendingStateUpdates ( ) ; assert ( ! ! stateUpdates , 'State updates should not be undefined' ) ; assert ( stateUpdates . length === numTransactions ) ; for ( let i = 0 ; i < numTransactions ; i ++ ) { stateUpdates [ i ] . should . equal ( transactionResults [ i ] . stateUpdate ) ; } } ) ; it ( 'Throws if executeTransaction throws' , async ( ) => { stateManager . throwOnExecuteTransaction ( ) ; try { await aggregator . ingestTransaction ( undefined ) ; assert ( false , 'This should have thrown' ) ; } catch ( e ) { } } ) ; it ( 'Throws if Transaction range is not valid' , async ( ) => { const transactionResult = TestUtils . generateNSequentialTransactionResults ( 1 ) [ 0 ] ; stateManager . setExecuteTransactionResults ( [ transactionResult ] ) ; const transaction = { depositAddress : '' , range : { start : transactionResult . validRanges [ 0 ] . start , end : transactionResult . validRanges [ 0 ] . end . add ( ONE ) , } , body : { } , } ; try { await aggregator . ingestTransaction ( transaction ) ; assert ( false , 'This should have thrown' ) ; } catch ( e ) { } } ) ; } ) ; } ) ;