def init_database(tmpdir, in_memory_database): database_path = ':memory:' if not in_memory_database: database_path = os.path.join(tmpdir.strpath, 'database.db') return StateChangeLog( storage_instance=StateChangeLogSQLiteBackend( database_path=database_path ) )
def __init__(self, chain, default_registry, private_key_bin, transport, discovery, config): if not isinstance(private_key_bin, bytes) or len(private_key_bin) != 32: raise ValueError('invalid private_key') invalid_timeout = ( config['settle_timeout'] < NETTINGCHANNEL_SETTLE_TIMEOUT_MIN or config['settle_timeout'] > NETTINGCHANNEL_SETTLE_TIMEOUT_MAX) if invalid_timeout: raise ValueError('settle_timeout must be in range [{}, {}]'.format( NETTINGCHANNEL_SETTLE_TIMEOUT_MIN, NETTINGCHANNEL_SETTLE_TIMEOUT_MAX)) self.token_to_channelgraph = dict() self.tokens_to_connectionmanagers = dict() self.manager_to_token = dict() self.swapkey_to_tokenswap = dict() self.swapkey_to_greenlettask = dict() self.identifier_to_statemanagers = defaultdict(list) self.identifier_to_results = defaultdict(list) # This is a map from a hashlock to a list of channels, the same # hashlock can be used in more than one token (for tokenswaps), a # channel should be removed from this list only when the lock is # released/withdrawn but not when the secret is registered. self.token_to_hashlock_to_channels = defaultdict( lambda: defaultdict(list)) self.chain = chain self.default_registry = default_registry self.config = config self.privkey = private_key_bin self.address = privatekey_to_address(private_key_bin) endpoint_registration_event = gevent.spawn( discovery.register, self.address, config['external_ip'], config['external_port'], ) endpoint_registration_event.link_exception( endpoint_registry_exception_handler) self.private_key = PrivateKey(private_key_bin) self.pubkey = self.private_key.public_key.format(compressed=False) self.protocol = RaidenProtocol( transport, discovery, self, config['protocol']['retry_interval'], config['protocol']['retries_before_backoff'], config['protocol']['nat_keepalive_retries'], config['protocol']['nat_keepalive_timeout'], config['protocol']['nat_invitation_timeout'], ) # TODO: remove this cyclic dependency transport.protocol = self.protocol self.message_handler = RaidenMessageHandler(self) self.state_machine_event_handler = StateMachineEventHandler(self) self.blockchain_events = BlockchainEvents() self.greenlet_task_dispatcher = GreenletTasksDispatcher() self.on_message = self.message_handler.on_message self.alarm = AlarmTask(chain) self.shutdown_timeout = config['shutdown_timeout'] self._block_number = None self.stop_event = Event() self.start_event = Event() self.chain.client.inject_stop_event(self.stop_event) self.transaction_log = StateChangeLog( storage_instance=StateChangeLogSQLiteBackend( database_path=config['database_path'])) self.wal = None self.database_path = config['database_path'] if self.database_path != ':memory:': self.database_dir = os.path.dirname(self.database_path) self.lock_file = os.path.join(self.database_dir, '.lock') self.snapshot_dir = os.path.join(self.database_dir, 'snapshots') self.serialization_file = os.path.join(self.snapshot_dir, 'data.pickle') if not os.path.exists(self.snapshot_dir): os.makedirs(self.snapshot_dir) # Prevent concurrent acces to the same db self.db_lock = filelock.FileLock(self.lock_file) else: self.database_dir = None self.lock_file = None self.snapshot_dir = None self.serialization_file = None self.db_lock = None # If the endpoint registration fails the node will quit, this must # finish before starting the protocol endpoint_registration_event.join() self.start()
def __init__(self, chain, private_key_bin, transport, discovery, config): if not isinstance(private_key_bin, bytes) or len(private_key_bin) != 32: raise ValueError('invalid private_key') if config['settle_timeout'] < NETTINGCHANNEL_SETTLE_TIMEOUT_MIN: raise ValueError('settle_timeout must be larger-or-equal to {}'.format( NETTINGCHANNEL_SETTLE_TIMEOUT_MIN )) # create lock file only if SQLite backend is file, to prevent two instances # from accesing a single db if config['database_path'] != ':memory:': self.db_lock = filelock.FileLock(path.dirname(config['database_path']) + "/.lock") self.db_lock.acquire(timeout=0) assert self.db_lock.is_locked else: self.db_lock = None private_key = PrivateKey(private_key_bin) pubkey = private_key.public_key.format(compressed=False) protocol = RaidenProtocol( transport, discovery, self, config['protocol']['retry_interval'], config['protocol']['retries_before_backoff'], config['protocol']['nat_keepalive_retries'], config['protocol']['nat_keepalive_timeout'], config['protocol']['nat_invitation_timeout'], ) transport.protocol = protocol self.token_to_channelgraph = dict() self.manager_to_token = dict() self.swapkey_to_tokenswap = dict() self.swapkey_to_greenlettask = dict() self.identifier_to_statemanagers = defaultdict(list) self.identifier_to_results = defaultdict(list) # This is a map from a hashlock to a list of channels, the same # hashlock can be used in more than one token (for tokenswaps), a # channel should be removed from this list only when the lock is # released/withdrawn but not when the secret is registered. self.token_to_hashlock_to_channels = defaultdict(lambda: defaultdict(list)) self.chain = chain self.config = config self.privkey = private_key_bin self.pubkey = pubkey self.private_key = private_key self.address = privatekey_to_address(private_key_bin) self.protocol = protocol message_handler = RaidenMessageHandler(self) state_machine_event_handler = StateMachineEventHandler(self) pyethapp_blockchain_events = PyethappBlockchainEvents() greenlet_task_dispatcher = GreenletTasksDispatcher() alarm = AlarmTask(chain) # prime the block number cache and set the callbacks self._blocknumber = alarm.last_block_number alarm.register_callback(self.poll_blockchain_events) alarm.register_callback(self.set_block_number) self.transaction_log = StateChangeLog( storage_instance=StateChangeLogSQLiteBackend( database_path=config['database_path'] ) ) registry_event = gevent.spawn( discovery.register, self.address, config['external_ip'], config['external_port'], ) self.alarm = alarm self.message_handler = message_handler self.state_machine_event_handler = state_machine_event_handler self.pyethapp_blockchain_events = pyethapp_blockchain_events self.greenlet_task_dispatcher = greenlet_task_dispatcher self.on_message = message_handler.on_message self.tokens_to_connectionmanagers = dict() self.serialization_file = None self.protocol.start() alarm.start() if config['database_path'] != ':memory:': snapshot_dir = os.path.join( path.dirname(self.config['database_path']), 'snapshots' ) if not os.path.exists(snapshot_dir): os.makedirs( snapshot_dir ) self.serialization_file = path.join( snapshot_dir, 'data.pickle', ) self.register_registry(self.chain.default_registry.address) self.restore_from_snapshots() registry_event.join()
def __init__(self, chain, private_key_bin, transport, discovery, config): if not isinstance(private_key_bin, bytes) or len(private_key_bin) != 32: raise ValueError('invalid private_key') if config['settle_timeout'] < NETTINGCHANNEL_SETTLE_TIMEOUT_MIN: raise ValueError( 'settle_timeout must be larger-or-equal to {}'.format( NETTINGCHANNEL_SETTLE_TIMEOUT_MIN)) private_key = PrivateKey(private_key_bin) pubkey = private_key.public_key.format(compressed=False) self.channelgraphs = dict() self.manager_token = dict() self.swapkeys_tokenswaps = dict() self.swapkeys_greenlettasks = dict() self.identifier_to_statemanagers = defaultdict(list) self.identifier_to_results = defaultdict(list) # This is a map from a hashlock to a list of channels, the same # hashlock can be used in more than one token (for tokenswaps), a # channel should be removed from this list only when the lock is # released/withdrawn but not when the secret is registered. self.tokens_hashlocks_channels = defaultdict(lambda: defaultdict(list)) self.chain = chain self.config = config self.privkey = private_key_bin self.pubkey = pubkey self.private_key = private_key self.address = privatekey_to_address(private_key_bin) self.protocol = RaidenProtocol(transport, discovery, self) transport.protocol = self.protocol message_handler = RaidenMessageHandler(self) state_machine_event_handler = StateMachineEventHandler(self) pyethapp_blockchain_events = PyethappBlockchainEvents() greenlet_task_dispatcher = GreenletTasksDispatcher() alarm = AlarmTask(chain) # prime the block number cache and set the callbacks self._blocknumber = alarm.last_block_number alarm.register_callback(lambda _: self.poll_blockchain_events()) alarm.register_callback(self.set_block_number) alarm.start() if config['max_unresponsive_time'] > 0: self.healthcheck = HealthcheckTask(self, config['send_ping_time'], config['max_unresponsive_time']) self.healthcheck.start() else: self.healthcheck = None self.transaction_log = StateChangeLog( storage_instance=StateChangeLogSQLiteBackend( database_path=config['database_path'])) self.alarm = alarm self.message_handler = message_handler self.state_machine_event_handler = state_machine_event_handler self.pyethapp_blockchain_events = pyethapp_blockchain_events self.greenlet_task_dispatcher = greenlet_task_dispatcher self.on_message = message_handler.on_message self.tokens_connectionmanagers = dict( ) # token_address: ConnectionManager
def __init__(self, chain, private_key_bin, transport, discovery, config): if not isinstance(private_key_bin, bytes) or len(private_key_bin) != 32: raise ValueError('invalid private_key') if config['settle_timeout'] < NETTINGCHANNEL_SETTLE_TIMEOUT_MIN: raise ValueError('settle_timeout must be larger-or-equal to {}'.format( NETTINGCHANNEL_SETTLE_TIMEOUT_MIN )) private_key = PrivateKey(private_key_bin) pubkey = private_key.public_key.format(compressed=False) protocol = RaidenProtocol( transport, discovery, self, config['protocol']['retry_interval'], config['protocol']['retries_before_backoff'], config['protocol']['nat_keepalive_retries'], config['protocol']['nat_keepalive_timeout'], config['protocol']['nat_invitation_timeout'], ) transport.protocol = protocol self.channelgraphs = dict() self.manager_token = dict() self.swapkeys_tokenswaps = dict() self.swapkeys_greenlettasks = dict() self.identifier_to_statemanagers = defaultdict(list) self.identifier_to_results = defaultdict(list) # This is a map from a hashlock to a list of channels, the same # hashlock can be used in more than one token (for tokenswaps), a # channel should be removed from this list only when the lock is # released/withdrawn but not when the secret is registered. self.tokens_hashlocks_channels = defaultdict(lambda: defaultdict(list)) self.chain = chain self.config = config self.privkey = private_key_bin self.pubkey = pubkey self.private_key = private_key self.address = privatekey_to_address(private_key_bin) self.protocol = protocol message_handler = RaidenMessageHandler(self) state_machine_event_handler = StateMachineEventHandler(self) pyethapp_blockchain_events = PyethappBlockchainEvents() greenlet_task_dispatcher = GreenletTasksDispatcher() alarm = AlarmTask(chain) # prime the block number cache and set the callbacks self._blocknumber = alarm.last_block_number alarm.register_callback(lambda _: self.poll_blockchain_events()) alarm.register_callback(self.set_block_number) alarm.start() self.transaction_log = StateChangeLog( storage_instance=StateChangeLogSQLiteBackend( database_path=config['database_path'] ) ) self.channels_serialization_path = None self.channels_queue_path = None if config['database_path'] != ':memory:': self.channels_serialization_path = path.join( path.dirname(self.config['database_path']), 'channels.pickle', ) self.channels_queue_path = path.join( path.dirname(self.config['database_path']), 'queues.pickle', ) if path.exists(self.channels_serialization_path): serialized_channels = list() with open(self.channels_serialization_path, 'r') as handler: try: while True: serialized_channels.append(pickle.load(handler)) except EOFError: pass for channel in serialized_channels: self.restore_channel(channel) if path.exists(self.channels_queue_path): with open(self.channels_queue_path, 'r') as handler: channel_state = pickle.load(handler) for restored_queue in channel_state['channel_queues']: self.restore_queue(restored_queue) self.protocol.receivedhashes_acks = channel_state['receivedhashes_acks'] self.protocol.nodeaddresses_nonces = channel_state['nodeaddresses_nonces'] self.alarm = alarm self.message_handler = message_handler self.state_machine_event_handler = state_machine_event_handler self.pyethapp_blockchain_events = pyethapp_blockchain_events self.greenlet_task_dispatcher = greenlet_task_dispatcher self.on_message = message_handler.on_message self.tokens_connectionmanagers = dict() # token_address: ConnectionManager