Пример #1
0
    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)
Пример #2
0
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
Пример #3
0
    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)
Пример #4
0
    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
Пример #5
0
    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()
Пример #6
0
    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")
Пример #7
0
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
Пример #8
0
    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)
Пример #9
0
#!/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
Пример #10
0
def _get_node_key(args):
    if args["node_key"] is not None:
        return args["node_key"]
    return btctxstore.BtcTxStore().create_wallet()
Пример #11
0
 def setUp(self):
     self.btctxstore = btctxstore.BtcTxStore()
Пример #12
0
#!/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()
Пример #13
0
    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.")