def setUpClass(cls): cls.btctxstore = btctxstore.BtcTxStore(testnet=False) cls.swarm = [] for i in range(SWARM_SIZE): # isolate swarm bootstrap_nodes = [("127.0.0.1", PORT + x) for x in range(i)][-20:] # create node node = storjnode.network.Node( cls.btctxstore.create_wallet(), port=(PORT + i), ksize=16, bootstrap_nodes=bootstrap_nodes, disable_data_transfer=True, refresh_neighbours_interval=0.0 ) cls.swarm.append(node) # stabalize network overlay time.sleep(WALK_TIMEOUT) for node in cls.swarm: node.refresh_neighbours() time.sleep(WALK_TIMEOUT) for node in cls.swarm: node.refresh_neighbours() time.sleep(WALK_TIMEOUT)
def is_complete(contract): # Must be valid validate(contract) # All fields must be filled if not _is_filled(contract): return False # TODO check other things that need to be logically correct # check duration duration = contract["store_duration"] begin = contract["store_begin"] end = contract["store_end"] if end - begin != duration: return False # check signatures _btcapi = btctxstore.BtcTxStore() message = _generate_signature_message(contract) renter_btc_address = util.hexnodeid_to_address(contract["renter_id"]) farmer_btc_address = util.hexnodeid_to_address(contract["farmer_id"]) if not _btcapi.verify_signature_unicode(renter_btc_address, contract["renter_signature"], message): return False # invalid renter signature if not _btcapi.verify_signature_unicode(farmer_btc_address, contract["farmer_signature"], message): return False # invalid renter signature return True
def __init__(self, key, ksize=20, alpha=3, storage=None): """ Create a server instance. This will start listening on the given port. Args: key: bitcoin wif/hwif to be used as id and for signing/encryption ksize (int): The k parameter from the kademlia paper alpha (int): The alpha parameter from the kademlia paper storage: implements :interface:`~kademlia.storage.IStorage` """ # TODO validate key is valid wif/hwif for mainnet or testnet testnet = False # FIXME get from wif/hwif self._btctxstore = btctxstore.BtcTxStore(testnet=testnet) # allow hwifs is_hwif = self._btctxstore.validate_wallet(key) self._key = self._btctxstore.get_key(key) if is_hwif else key # XXX Server.__init__ cannot call super because of StorjProtocol # passing the protocol class should be added upstream self.ksize = ksize self.alpha = alpha self.log = logging.getLogger(__name__) self.storage = storage or ForgetfulStorage() self.node = Node(self.get_id()) self.protocol = StorjProtocol(self.node, self.storage, ksize) self.refreshLoop = LoopingCall(self.refreshTable).start(3600)
def __init__(self, server_url, wif, connection_retry_limit, connection_retry_delay): self._server_url = server_url self._server_address = None self.retry_limit = connection_retry_limit self.retry_delay = connection_retry_delay # TODO pass testnet and dryrun options self.btctxstore = btctxstore.BtcTxStore() self.wif = wif
def __init__(self, key, ksize=20, alpha=3, storage=None, max_messages=1024, default_hop_limit=64, refresh_neighbours_interval=0.0): """ Create a server instance. This will start listening on the given port. Args: key (str): Bitcoin wif/hwif for auth, encryption and node id. ksize (int): The k parameter from the kademlia paper. alpha (int): The alpha parameter from the kademlia paper storage: implements :interface:`~kademlia.storage.IStorage` refresh_neighbours_interval (float): Auto refresh neighbours. """ self._default_hop_limit = default_hop_limit self._refresh_neighbours_interval = refresh_neighbours_interval # TODO validate key is valid wif/hwif for mainnet or testnet testnet = False # FIXME get from wif/hwif self._btctxstore = btctxstore.BtcTxStore(testnet=testnet) # allow hwifs is_hwif = self._btctxstore.validate_wallet(key) self.key = self._btctxstore.get_key(key) if is_hwif else key # XXX Server.__init__ cannot call super because of StorjProtocol # passing the protocol class should be added upstream self.ksize = ksize self.alpha = alpha self.log = logging.getLogger(__name__) self.storage = storage or ForgetfulStorage() self.node = Node(self.get_id()) self.protocol = StorjProtocol(self.node, self.storage, ksize, max_messages=max_messages, max_hop_limit=self._default_hop_limit) self.refreshLoop = LoopingCall(self.refreshTable).start(3600) self._start_threads()
def setUpClass(cls): # start profiler cls.profile = cProfile.Profile() cls.profile.enable() # create swarm print("TEST: creating swarm") cls.btctxstore = btctxstore.BtcTxStore(testnet=False) cls.swarm = [] for i in range(SWARM_SIZE): # isolate swarm bootstrap_nodes = [("127.0.0.1", PORT + x) for x in range(i)][-20:] # create node node = storjnode.network.Node(cls.btctxstore.create_wallet(), port=(PORT + i), ksize=8, bootstrap_nodes=bootstrap_nodes, refresh_neighbours_interval=0.0, max_messages=MAX_MESSAGES, store_config={STORAGE_DIR: None}, nat_type="preserving", node_type="passive", wan_ip=WAN_IP, disable_data_transfer=True) cls.swarm.append(node) msg = "TEST: created node {0} @ 127.0.0.1:{1}" print(msg.format(node.get_hex_id(), node.port)) # stabalize network overlay print("TEST: stabalize network overlay") time.sleep(WALK_TIMEOUT) for node in cls.swarm: node.refresh_neighbours() time.sleep(WALK_TIMEOUT) for node in cls.swarm: node.refresh_neighbours() time.sleep(WALK_TIMEOUT) print("TEST: created swarm")
def sign(contract, key): _btcapi = btctxstore.BtcTxStore() # must be a valid contract validate(contract) # everything but signatures must be given exclude = ["farmer_signature", "renter_signature"] assert(_is_filled(contract, exclude=exclude)) # key must be wif or hwif wif = None if _btcapi.validate_wallet(key): # hwif given wif = _btcapi.get_key(key) elif _btcapi.validate_key(key): # wif given wif = key assert(wif is not None) # key is not wif or hwif btc_address = _btcapi.get_address(wif) # signing key must be from farmer or renter hexnodeid = binascii.hexlify(util.address_to_nodeid(btc_address)) assert(hexnodeid in [contract["farmer_id"], contract["renter_id"]]) # not already signed sigfield = None if contract["renter_id"] == hexnodeid: sigfield = "renter_signature" elif contract["farmer_id"] == hexnodeid: sigfield = "farmer_signature" assert(sigfield is not None) # impossable state assert(contract[sigfield] is None) # not already signed # sign contract message = _generate_signature_message(contract) signature = _btcapi.sign_unicode(wif, message) contract[sigfield] = signature return contract
def setUpClass(cls): cls.btctxstore = btctxstore.BtcTxStore(testnet=False) cls.swarm = [] for i in range(TEST_SWARM_SIZE): # isolate swarm bootstrap_nodes = [("127.0.0.1", 3000 + x) for x in range(i) ][-3:] # only knows the last 3 nodes # create node node = storjnode.network.BlockingNode( cls.btctxstore.create_wallet(), port=(3000 + i), bootstrap_nodes=bootstrap_nodes, start_reactor=False) cls.swarm.append(node) # start reactor cls.reactor_thread = threading.Thread( target=reactor.run, kwargs={"installSignalHandlers": False}) cls.reactor_thread.start() # wait time.sleep(12)
#!/usr/bin/env python # from examples/multinode_usage.py import time import threading import storjnode import btctxstore from twisted.internet import reactor # create alice node alice_wallet = btctxstore.BtcTxStore().create_wallet() # hwif alice_node = storjnode.network.BlockingNode(alice_wallet, port=4653, start_reactor=False) # create bob node bob_key = btctxstore.BtcTxStore().create_wallet() # wif bob_node = storjnode.network.BlockingNode(bob_key, port=4654, start_reactor=False) # start twisted reactor yourself reactor_thread = threading.Thread(target=reactor.run, kwargs={"installSignalHandlers": False}) reactor_thread.start() time.sleep(12) # Giving node some time to find peers # use nodes alice_node["examplekey"] = "examplevalue" # alice inserts value stored_value = bob_node["examplekey"] # bob retrievs value print("{key} => {value}".format(key="examplekey", value=stored_value)) # stop twisted reactor
def _get_node_key(args): if args["node_key"] is not None: return args["node_key"] return btctxstore.BtcTxStore().create_wallet()
def setUp(self): self.btctxstore = btctxstore.BtcTxStore()
#!/usr/bin/env python # from examples/usage.py import time import storjnode import btctxstore # start node node_key = btctxstore.BtcTxStore().create_key() # btc wif or hwif node = storjnode.network.BlockingNode(node_key) # using default port 4653 time.sleep(12) # Giving node some time to find peers # The blocking node interface is very simple and behaves like a dict. node["examplekey"] = "examplevalue" # put key value pair into DHT retrieved = node["examplekey"] # retrieve value by key from DHT print("{key} => {value}".format(key="examplekey", value=retrieved)) # A node does not know of its size or all entries. try: node.items() except NotImplementedError as e: print(e) # A node can only write to the DHT. try: del node["examplekey"] except NotImplementedError as e: print(e) # stop twisted reactor to disconnect from network node.stop_reactor()
def test_multiple_transfers(self): def make_random_file(file_size=1024 * 100, directory=self.test_storage_dir): content = os.urandom(file_size) file_name = hashlib.sha256(content[0:64]).hexdigest() path = storjnode.util.full_path(os.path.join(directory, file_name)) with open(path, "wb") as fp: fp.write(content) return {"path": path, "content": content} # Sample node. wallet = btctxstore.BtcTxStore(testnet=True, dryrun=True) wif = wallet.get_key(wallet.create_wallet()) store_config = { os.path.join(self.test_storage_dir, "storage"): { "limit": 0 } } client = FileTransfer(pyp2p.net.Net(node_type="simultaneous", nat_type="preserving", net_type="direct", passive_port=60400, dht_node=pyp2p.dht_msg.DHT(), debug=1), wif=wif, store_config=store_config) _log.debug("Net started") # Make random file rand_file_infos = [make_random_file()] # Move file to storage directory. file_infos = [client.move_file_to_storage(rand_file_infos[0]["path"])] # Delete original file. os.remove(rand_file_infos[0]["path"]) _log.debug("Testing upload") # Upload file from storage. for file_info in file_infos: client.data_request("upload", file_info["data_id"], 0, TEST_NODE["unl"]) # Process file transfers. duration = 15 timeout = time.time() + duration while time.time() <= timeout or client.is_queued(): process_transfers(client) time.sleep(0.002) # Check upload exists. for i in range(0, 1): url = TEST_NODE["web"] + file_infos[i]["data_id"] r = requests.get(url, timeout=3) if r.status_code != 200: _log.debug(r.status_code) assert (0) else: assert (r.content == rand_file_infos[i]["content"]) _log.debug("File upload succeeded.") # Delete storage file copy. client.remove_file_from_storage(file_infos[0]["data_id"]) # Download file from storage. _log.debug("Testing download.") for file_info in file_infos: client.data_request("download", file_info["data_id"], 0, TEST_NODE["unl"]) # Process file transfers. duration = 15 timeout = time.time() + duration while time.time() <= timeout or client.is_queued(): process_transfers(client) time.sleep(0.002) # Check we received this file. for i in range(0, 1): path = storage.manager.find(store_config, file_infos[i]["data_id"]) if not os.path.isfile(path): assert (0) else: with open(path, "r") as fp: content = fp.read() assert (content == rand_file_infos[i]["content"]) # Delete storage file copy. client.remove_file_from_storage(file_infos[0]["data_id"]) # Stop networking. client.net.stop() _log.debug("Download succeeded.")