예제 #1
0
    def setup_listeners(self):
        """Setup subsystems that scan for incoming events from geth."""
        wallet_contract = HostedWallet.contract_class(self.web3)
        token_contract = Token.contract_class(self.web3)

        self.eth_wallet_listener = EthWalletListener(self.web3, wallet_contract, self.dbsession, self.asset_network_id, registry=self.registry)

        self.eth_token_listener = EthTokenListener(self.web3, token_contract, self.dbsession, self.asset_network_id, registry=self.registry)

        self.confirmation_updater = DatabaseConfirmationUpdater(self.web3, self.dbsession, self.asset_network_id, self.registry)
        self.op_queue_manager = OperationQueueManager(self.web3, self.dbsession, self.asset_network_id, self.registry)
예제 #2
0
 def setup_listeners(self):
     """Setup subsystems that scan for incoming events from geth."""
     wallet_contract = HostedWallet.contract_class(self.web3)
     token_contract = Token.contract_class(self.web3)
     self.eth_wallet_listener = EthWalletListener(self.web3, wallet_contract, self.dbsession, self.asset_network_id, registry=self.registry)
     self.eth_token_listener = EthTokenListener(self.web3, token_contract, self.dbsession, self.asset_network_id, registry=self.registry)
     self.confirmation_updater = DatabaseConfirmationUpdater(self.web3, self.dbsession, self.asset_network_id, self.registry)
     self.op_queue_manager = OperationQueueManager(self.web3, self.dbsession, self.asset_network_id, self.registry)
예제 #3
0
class EthereumService:
    """Ethereum service takes care of synchronizing operations between internal database and Ethereum daemon.

    We take a simple approach where we have one service / db running one single thread which does all operations serial manner.

    When testing, we call functions directly.
    """

    def __init__(self, web3: Web3, asset_network_id: UUID, dbsession: Session, registry: Registry):

        assert isinstance(web3, Web3)
        assert isinstance(registry, Registry)
        self.web3 = web3

        self.asset_network_id = asset_network_id
        self.dbsession = dbsession
        self.registry = registry

        self.setup_listeners()

    def get_withdraw_required_confirmation_count(self):
        """How many confirmations we check on withdraw ops until we mark them confirmed."""
        return 1

    def setup_listeners(self):
        """Setup subsystems that scan for incoming events from geth."""
        wallet_contract = HostedWallet.contract_class(self.web3)
        token_contract = Token.contract_class(self.web3)

        self.eth_wallet_listener = EthWalletListener(self.web3, wallet_contract, self.dbsession, self.asset_network_id, registry=self.registry)

        self.eth_token_listener = EthTokenListener(self.web3, token_contract, self.dbsession, self.asset_network_id, registry=self.registry)

        self.confirmation_updater = DatabaseConfirmationUpdater(self.web3, self.dbsession, self.asset_network_id, self.registry)
        self.op_queue_manager = OperationQueueManager(self.web3, self.dbsession, self.asset_network_id, self.registry)

    def run_listener_operations(self) -> Tuple[int, int]:
        """Return number of operations events read and handled."""
        total_success = total_failure = 0

        for func in (self.eth_wallet_listener.poll, self.eth_token_listener.poll):
            success, failure = func()
            total_success += success
            total_failure += failure

        return total_success, total_failure

    def run_confirmation_updates(self) -> Tuple[int, int]:
        return self.confirmation_updater.poll()

    def run_waiting_operations(self) -> Tuple[int, int]:
        """Run all operations that are waiting to be executed.

        :return: Number of operations (performed successfully, failed)
        """
        return self.op_queue_manager.run_waiting_operations()

    def update_heartbeat(self):
        # Tell web interface we are still alive

        block_number = self.web3.eth.blockNumber
        block = self.web3.eth.getBlock(block_number)
        block_time = int(block["timestamp"])
        update_heart_beat(self.dbsession, self.asset_network_id, block_number, block_time)

    def run_event_cycle(self, cycle_num=None) -> Tuple[int, int]:
        """Run full event cycle for all operations."""
        total_success = total_failure = 0

        for func in (self.run_waiting_operations, self.run_listener_operations, self.run_confirmation_updates):
            # Make sure all transactions are closed before and after running ops
            # logger.info("Running %s", func)
            ensure_transactionless("TX management Error. Starting to process {} in event cycle {}".format(func, cycle_num))
            success, failure = func()
            ensure_transactionless()
            total_success += success
            total_failure += failure

        self.update_heartbeat()

        return total_success, total_failure
예제 #4
0
class EthereumService:
    """Ethereum service takes care of synchronizing operations between internal database and Ethereum daemon.

    We take a simple approach where we have one service / db running one single thread which does all operations serial manner.

    When testing, we call functions directly.
    """

    def __init__(self, web3: Web3, asset_network_id: UUID, dbsession: Session, registry: Registry):

        assert isinstance(web3, Web3)
        assert isinstance(registry, Registry)
        self.web3 = web3

        self.asset_network_id = asset_network_id
        self.dbsession = dbsession
        self.registry = registry

        self.setup_listeners()

    def get_withdraw_required_confirmation_count(self):
        """How many confirmations we check on withdraw ops until we mark them confirmed."""
        return 1

    def setup_listeners(self):
        """Setup subsystems that scan for incoming events from geth."""
        wallet_contract = HostedWallet.contract_class(self.web3)
        token_contract = Token.contract_class(self.web3)
        self.eth_wallet_listener = EthWalletListener(self.web3, wallet_contract, self.dbsession, self.asset_network_id, registry=self.registry)
        self.eth_token_listener = EthTokenListener(self.web3, token_contract, self.dbsession, self.asset_network_id, registry=self.registry)
        self.confirmation_updater = DatabaseConfirmationUpdater(self.web3, self.dbsession, self.asset_network_id, self.registry)
        self.op_queue_manager = OperationQueueManager(self.web3, self.dbsession, self.asset_network_id, self.registry)

    def run_listener_operations(self) -> Tuple[int, int]:
        """Return number of operations events read and handled."""
        total_success = total_failure = 0

        for func in (self.eth_wallet_listener.poll, self.eth_token_listener.poll):
            success, failure = func()
            total_success += success
            total_failure += failure

        return total_success, total_failure

    def run_confirmation_updates(self) -> Tuple[int, int]:
        return self.confirmation_updater.poll()

    def run_waiting_operations(self) -> Tuple[int, int]:
        """Run all operations that are waiting to be executed.

        :return: Number of operations (performed successfully, failed)
        """
        return self.op_queue_manager.run_waiting_operations()

    def update_heartbeat(self):
        # Tell web interface we are still alive

        block_number = self.web3.eth.blockNumber
        block = self.web3.eth.getBlock(block_number)
        block_time = int(block["timestamp"])
        update_heart_beat(self.dbsession, self.asset_network_id, block_number, block_time)

    def run_event_cycle(self, cycle_num=None) -> Tuple[int, int]:
        """Run full event cycle for all operations."""
        total_success = total_failure = 0

        for func in (self.run_waiting_operations, self.run_listener_operations, self.run_confirmation_updates):
            # Make sure all transactions are closed before and after running ops
            # logger.info("Running %s", func)
            ensure_transactionless("TX management Error. Starting to process {} in event cycle {}".format(func, cycle_num))
            success, failure = func()
            ensure_transactionless()
            total_success += success
            total_failure += failure

        self.update_heartbeat()

        return total_success, total_failure