Ejemplo n.º 1
0
 def __init__(self, bsddb_env, filename):
     self.bsddb_env = bsddb_env
     self.filename = filename
     self.varstr_serializer = VarstrSerializer()
     self.uint256_serializer = Uint256Serializer("")
     self.wallet_tx_serializer = WalletTxSerializer()
     self.master_key_serializer = MasterKeySerializer()
     self.reset_wallet()
     self.db = bsddb.db.DB(self.bsddb_env.dbenv)
     self.dbflags = bsddb.db.DB_THREAD
Ejemplo n.º 2
0
class AlertMessageSerializer(Serializer):
    ALERT = Structure([VarstrSerializer("payload"),
                       VarstrSerializer("signature")])
    PAYLOAD = AlertPayloadSerializer()
    def serialize(self, alert_msg):
        payload_data = AlertPayloadSerializer().serialize(alert_msg.payload)
        return (self.ALERT.serialize([payload_data, alert_msg.signature]))

    def deserialize(self, data, cursor=0):
        (payload_data, signature), cursor = self.ALERT.deserialize(data, cursor)
        payload, _ = AlertPayloadSerializer().deserialize(payload_data)
        return (AlertMessage(payload, signature), cursor)
Ejemplo n.º 3
0
class VarstrScriptSerializer(Serializer):
    def __init__(self):
        self.serializer = ScriptSerializer()
        self.strencoder = VarstrSerializer()

    def serialize(self, script):
        scriptstr = self.serializer.serialize(script)
        return (self.strencoder.serialize(scriptstr))

    def get_size(self, script):
        return self.strencoder.get_size_for_len(self.serializer.get_size(script))

    def deserialize(self, data, cursor=0):
        scriptstr, newcursor = self.strencoder.deserialize(data, cursor)
        return (self.serializer.deserialize(scriptstr), newcursor)
Ejemplo n.º 4
0
class VarstrScriptSerializer(Serializer):
    def __init__(self):
        self.serializer = ScriptSerializer()
        self.strencoder = VarstrSerializer()

    def serialize(self, script):
        scriptstr = self.serializer.serialize(script)
        return (self.strencoder.serialize(scriptstr))

    def get_size(self, script):
        return self.strencoder.get_size_for_len(
            self.serializer.get_size(script))

    def deserialize(self, data, cursor=0):
        scriptstr, newcursor = self.strencoder.deserialize(data, cursor)
        return (self.serializer.deserialize(scriptstr), newcursor)
Ejemplo n.º 5
0
 def __init__(self, bsddb_env, filename):
     self.bsddb_env = bsddb_env
     self.filename = filename
     self.varstr_serializer = VarstrSerializer()
     self.uint256_serializer = Uint256Serializer("")
     self.wallet_tx_serializer = WalletTxSerializer()
     self.master_key_serializer = MasterKeySerializer()
     self.reset_wallet()
     self.db = bsddb.db.DB(self.bsddb_env.dbenv)
     self.dbflags = bsddb.db.DB_THREAD
Ejemplo n.º 6
0
class MasterKeySerializer():
    MASTER_KEY = Structure([
        VarstrSerializer(),
        VarstrSerializer(),
        Field("<I"),
        Field("<I"),
        VarstrSerializer()
    ])

    def serialize(self, master_key):
        return (self.MASTER_KEY.serialize([
            master_key.crypted_key, master_key.salt,
            master_key.derivation_method, master_key.derive_iterations,
            master_key.other_derivation_parameters
        ]))

    def deserialize(self, data, cursor):
        master_key_fields, cursor = self.MASTER_KEY.deserialize(data, cursor)
        (crypted_key, salt, derivation_method, derive_iterations,
         other_derivation_parameters) = master_key_fields
        return (MasterKey(crypted_key, salt, derivation_method,
                          derive_iterations,
                          other_derivation_parameters), cursor)
Ejemplo n.º 7
0
class AlertPayloadSerializer(Serializer):
    PAYLOAD = Structure([Field("<I", "version"),
                         Field("<Q", "relay_until"),
                         Field("<Q", "expiration"),
                         Field("<I", "id"),
                         Field("<I", "cancel"),
                         VarsizelistSerializer(VarintSerializer("count"), VarintSerializer("set_cancel")),
                         Field("<I", "min_ver"),
                         Field("<I", "max_ver"),
                         VarsizelistSerializer(VarintSerializer("count"), VarstrSerializer("set_sub_ver")),
                         Field("<I", "priority"),
                         VarstrSerializer("comment"),
                         VarstrSerializer("statusbar"),
                         VarstrSerializer("reserved")])
    
    def serialize(self, alert_payload):
        return (self.PAYLOAD.serialize([alert_payload.version, 
                                        alert_payload.relay_until,
                                        alert_payload.expiration,
                                        alert_payload.id,
                                        alert_payload.cancel,
                                        alert_payload.set_cancel,
                                        alert_payload.min_ver,
                                        alert_payload.max_ver,
                                        alert_payload.set_sub_ver,
                                        alert_payload.priority,
                                        alert_payload.comment,
                                        alert_payload.statusbar,
                                        alert_payload.reserved]))

    def deserialize(self, data, cursor=0):
        payload_fields, cursor = self.PAYLOAD.deserialize(data, cursor)
        (version, relay_until, expiration, id, cancel, set_cancel, min_ver, max_ver, \
         set_sub_ver, priority,  comment, statusbar, reserved) = payload_fields
        return (AlertPayload(version, relay_until, expiration, id, cancel, 
                             set(set_cancel), min_ver, max_ver, set(set_sub_ver), priority,
                             comment, statusbar, reserved), cursor)
Ejemplo n.º 8
0
class VersionMessageSerializer(Serializer):
    VERSION_STRUCT = Structure([
        Field("<I", "version"),
        Field("<Q", "services"),
        Field("<Q", "timestamp"),
        NetAddrSerializer("addr_me"),
        NetAddrSerializer("addr_you"),
        Field("<Q", "nonce"),
        VarstrSerializer("sub_version_num"),
        Field("<I", "start_height")
    ], "version_message")

    def serialize(self, version_msg):
        return (self.VERSION_STRUCT.serialize([
            version_msg.version, version_msg.services, version_msg.timestamp,
            version_msg.addr_me, version_msg.addr_you, version_msg.nonce,
            version_msg.sub_version_num, version_msg.start_height
        ]))

    def deserialize(self, data, cursor=0):
        result, cursor = self.VERSION_STRUCT.deserialize(data, cursor)
        return (VersionMessage(*result), cursor)
Ejemplo n.º 9
0
class BSDDBWalletDatabase(WalletDatabaseInterface):
    def __init__(self, bsddb_env, filename):
        self.bsddb_env = bsddb_env
        self.filename = filename
        self.varstr_serializer = VarstrSerializer()
        self.uint256_serializer = Uint256Serializer("")
        self.wallet_tx_serializer = WalletTxSerializer()
        self.master_key_serializer = MasterKeySerializer()
        self.reset_wallet()
        self.db = bsddb.db.DB(self.bsddb_env.dbenv)
        self.dbflags = bsddb.db.DB_THREAD

    def open(self):
        #self.bsddb_env.dbenv.fileid_reset(self.filename)
        self.dbtxn = self.bsddb_env.dbenv.txn_begin()
        self.db.open(self.filename,
                     "main",
                     bsddb.db.DB_BTREE,
                     self.dbflags,
                     txn=self.dbtxn)
        self.dbtxn.commit()
        self.dbtxn = None
        self._read_wallet()

    def create(self):
        #create empty database
        self.dbtxn = self.bsddb_env.dbenv.txn_begin()
        self.db.open(self.filename,
                     "main",
                     bsddb.db.DB_BTREE,
                     self.dbflags | bsddb.db.DB_CREATE,
                     txn=self.dbtxn)
        self.dbtxn.commit()
        self.dbtxn = None

    def begin_updates(self):
        self.dbtxn = self.bsddb_env.dbenv.txn_begin()

    def commit_updates(self):
        self.dbtxn.commit()
        #Synch to disk as wallet changes should not be lost
        self.db.sync()
        self.dbtxn = None

    def get_receive_key(self):
        if len(self.poolkeys) == 0:
            raise Exception("get_receive_key: No keys remaining")
        num, poolkey = next(self.poolkeys.iteritems())
        return poolkey.public_key

    def allocate_key(self, public_key, address, label=None, ischange=False):
        num = self.poolkeys_by_public_key[public_key].poolnum
        if num is None:
            raise Exception("allocate_pool_key: Can't find pool public_key")
        del self.poolkeys_by_public_key[public_key]
        del self.poolkeys[num]
        self.db.delete("\x04pool" + struct.pack("<q", num), txn=self.dbtxn)

        if (label and not ischange):
            self.set_label(address, label)

    def reset_wallet(self):
        self.master_keys = {}
        self.crypted_keys = {}
        self.keys = {}
        self.names = {}
        self.settings = []
        self.txs = {}
        self.poolkeys = {}
        self.poolkeys_by_public_key = {}

    def _read_entries(self, label):
        for key, value in self.db.items():
            lab, key_cursor = self.varstr_serializer.deserialize(key, 0)
            if lab == label:
                yield (key, key_cursor, value, 0)

    def _read_keys(self):
        for key, key_cursor, value, value_cursor in self._read_entries("key"):
            public_key, _ = self.varstr_serializer.deserialize(key, key_cursor)
            private_key, _ = self.varstr_serializer.deserialize(
                value, value_cursor)
            self.keys[public_key] = WalletKeypair(public_key, private_key)

    def _read_crypted_keys(self):
        for key, key_cursor, value, value_cursor in self._read_entries("ckey"):
            public_key, _ = self.varstr_serializer.deserialize(key, key_cursor)
            crypted_secret, _ = self.varstr_serializer.deserialize(
                value, value_cursor)
            self.crypted_keys[public_key] = crypted_secret

    def _read_master_keys(self):
        for key, key_cursor, value, value_cursor in self._read_entries("mkey"):
            id, = struct.unpack_from("<I", key, key_cursor)
            self.master_keys[
                id], cursor = self.master_key_serializer.deserialize(
                    value, value_cursor)

    def _read_names(self):
        for key, key_cursor, value, value_cursor in self._read_entries("name"):
            address_bytestr, _ = self.varstr_serializer.deserialize(
                key, key_cursor)
            name, _ = self.varstr_serializer.deserialize(value, value_cursor)
            address = BitcoinAddress.from_base58addr(address_bytestr)
            self.names[address] = WalletName(name, address)

    def _read_txs(self):
        for key, key_cursor, value, value_cursor in self._read_entries("tx"):
            hash, _ = self.uint256_serializer.deserialize(key, key_cursor)
            wallet_tx, _ = self.wallet_tx_serializer.deserialize(
                value, value_cursor)
            self.txs[hash] = wallet_tx

    def _read_poolkeys(self):
        for key, key_cursor, value, value_cursor in self._read_entries("pool"):
            poolnum, = struct.unpack_from("<q", key, key_cursor)
            version, = struct.unpack_from("<I", value, 0)
            time, = struct.unpack_from("<q", value, 4)
            public_key, _ = self.varstr_serializer.deserialize(value, 12)
            self.poolkeys[poolnum] = WalletPoolKey(poolnum, version, time,
                                                   public_key)
            self.poolkeys_by_public_key[public_key] = self.poolkeys[poolnum]

    def _read_wallet(self):
        self.reset_wallet()
        self._read_keys()
        self._read_crypted_keys()
        self._read_master_keys()
        self._read_names()
        self._read_txs()
        self._read_poolkeys()

    def get_keys(self):
        return self.keys

    def get_crypted_keys(self):
        return self.crypted_keys

    def get_wallet_txs(self):
        return self.txs

    def get_names(self):
        return self.names

    def get_poolkeys(self):
        return self.poolkeys

    def add_poolkey(self, poolkey):
        self.db.put("\x04pool" + struct.pack("<q", poolkey.poolnum),
                    struct.pack("<I", poolkey.version) + \
                    struct.pack("<q", poolkey.time) + \
                    self.varstr_serializer.serialize(poolkey.public_key),
                    txn=self.dbtxn)
        self.poolkeys[poolkey.poolnum] = poolkey
        self.poolkeys_by_public_key[poolkey.public_key] = self.poolkeys[
            poolkey.poolnum]

    def set_label(self, address, label):
        self.names[address] = WalletName(label, address)
        address = self.varstr_serializer.serialize(address.to_base58addr())
        name = self.varstr_serializer.serialize(label)
        self.db.put("\x04name" + address, name, txn=self.dbtxn)

    def add_name(self, wallet_name):
        pass

    def add_keypair(self, wallet_keypair):
        pass

    def set_transaction(self, hashtx, wallet_tx):
        self.txs[hashtx] = wallet_tx
        key = self.uint256_serializer.serialize(hashtx)
        value = self.wallet_tx_serializer.serialize(wallet_tx)
        self.db.put("\x02tx" + key, value, txn=self.dbtxn)

    def get_transaction(self, hashtx):
        return self.txs[hashtx]

    def del_transaction(self, hashtx):
        del self.txs[hashtx]
        self.db.delete("\x02tx" + self.uint256_serializer.serialize(hashtx),
                       txn=self.dbtxn)

    def del_poolkey(self, num):
        del self.poolkeys[num]
        self.db.delete("\x04pool" + struct.pack("<I", num))

    def add_master_key(self, master_key):
        id = max(self.master_keys.keys() + [0]) + 1
        key = "\x04mkey" + struct.pack("<I", id)
        value = self.master_key_serializer.serialize(master_key)
        self.db.put(key, value, txn=self.dbtxn)
        self.master_keys[id] = master_key

    def add_crypted_key(self, public_key, crypted_secret):
        self.db.put("\x04ckey" + self.varstr_serializer.serialize(public_key),
                    self.varstr_serializer.serialize(crypted_secret),
                    txn=self.dbtxn)
        self.crypted_keys[public_key] = crypted_secret

    def get_master_keys(self):
        return (self.master_keys)

    def get_version(self):
        return (struct.unpack("<I", self.db["\x07version"])[0])

    def set_version(self, version):
        self.db["\x07version"] = struct.pack("<I", version)

    """ Return wallet's BlockLocator or None if not found """

    def get_block_locator(self):
        if self.db.has_key("\x09bestblock"):
            serializer = BlockLocatorSerializer()
            block_locator, cursor = serializer.deserialize(
                self.db["\x09bestblock"], 0)
            return block_locator

    def set_blocklocator(self, blocklocator):
        serializer = BlockLocatorSerializer()
        self.db["\x09bestblock"] = serializer.serialize(blocklocator)

    def __str__(self):
        keys_str = "\n".join("    " + str(k) for k in self.get_keypairs())
        pool_keys_str = "\n".join("    " + str(k) for k in self.get_poolkeys())
        names_str = "\n".join("    " + str(k) for k in self.get_names())
        tx_str = "\n".join("    " + str(k) for k in self.get_wallet_txs())
        return "Wallet\n  keys:\n" + keys_str + "pool:\n" + pool_keys_str + "\n  names:\n" + names_str + "\n  txs:\n" + tx_str
Ejemplo n.º 10
0
 def __init__(self):
     self.serializer = ScriptSerializer()
     self.strencoder = VarstrSerializer()
Ejemplo n.º 11
0
class BSDDBWalletDatabase(WalletDatabaseInterface):
    def __init__(self, bsddb_env, filename):
        self.bsddb_env = bsddb_env
        self.filename = filename
        self.varstr_serializer = VarstrSerializer()
        self.uint256_serializer = Uint256Serializer("")
        self.wallet_tx_serializer = WalletTxSerializer()
        self.master_key_serializer = MasterKeySerializer()
        self.reset_wallet()
        self.db = bsddb.db.DB(self.bsddb_env.dbenv)
        self.dbflags = bsddb.db.DB_THREAD

    def open(self):
        # self.bsddb_env.dbenv.fileid_reset(self.filename)
        self.dbtxn = self.bsddb_env.dbenv.txn_begin()
        self.db.open(self.filename, "main", bsddb.db.DB_BTREE, self.dbflags, txn=self.dbtxn)
        self.dbtxn.commit()
        self.dbtxn = None
        self._read_wallet()

    def create(self):
        # create empty database
        self.dbtxn = self.bsddb_env.dbenv.txn_begin()
        self.db.open(self.filename, "main", bsddb.db.DB_BTREE, self.dbflags | bsddb.db.DB_CREATE, txn=self.dbtxn)
        self.dbtxn.commit()
        self.dbtxn = None

    def begin_updates(self):
        self.dbtxn = self.bsddb_env.dbenv.txn_begin()

    def commit_updates(self):
        self.dbtxn.commit()
        # Synch to disk as wallet changes should not be lost
        self.db.sync()
        self.dbtxn = None

    def get_receive_key(self):
        if len(self.poolkeys) == 0:
            raise Exception("get_receive_key: No keys remaining")
        num, poolkey = next(self.poolkeys.iteritems())
        return poolkey.public_key

    def allocate_key(self, public_key, address, label=None, ischange=False):
        num = self.poolkeys_by_public_key[public_key].poolnum
        if num is None:
            raise Exception("allocate_pool_key: Can't find pool public_key")
        del self.poolkeys_by_public_key[public_key]
        del self.poolkeys[num]
        self.db.delete("\x04pool" + struct.pack("<q", num), txn=self.dbtxn)

        if label and not ischange:
            self.set_label(address, label)

    def reset_wallet(self):
        self.master_keys = {}
        self.crypted_keys = {}
        self.keys = {}
        self.names = {}
        self.settings = []
        self.txs = {}
        self.poolkeys = {}
        self.poolkeys_by_public_key = {}

    def _read_entries(self, label):
        for key, value in self.db.items():
            lab, key_cursor = self.varstr_serializer.deserialize(key, 0)
            if lab == label:
                yield (key, key_cursor, value, 0)

    def _read_keys(self):
        for key, key_cursor, value, value_cursor in self._read_entries("key"):
            public_key, _ = self.varstr_serializer.deserialize(key, key_cursor)
            private_key, _ = self.varstr_serializer.deserialize(value, value_cursor)
            self.keys[public_key] = WalletKeypair(public_key, private_key)

    def _read_crypted_keys(self):
        for key, key_cursor, value, value_cursor in self._read_entries("ckey"):
            public_key, _ = self.varstr_serializer.deserialize(key, key_cursor)
            crypted_secret, _ = self.varstr_serializer.deserialize(value, value_cursor)
            self.crypted_keys[public_key] = crypted_secret

    def _read_master_keys(self):
        for key, key_cursor, value, value_cursor in self._read_entries("mkey"):
            id, = struct.unpack_from("<I", key, key_cursor)
            self.master_keys[id], cursor = self.master_key_serializer.deserialize(value, value_cursor)

    def _read_names(self):
        for key, key_cursor, value, value_cursor in self._read_entries("name"):
            address_bytestr, _ = self.varstr_serializer.deserialize(key, key_cursor)
            name, _ = self.varstr_serializer.deserialize(value, value_cursor)
            address = BitcoinAddress.from_base58addr(address_bytestr)
            self.names[address] = WalletName(name, address)

    def _read_txs(self):
        for key, key_cursor, value, value_cursor in self._read_entries("tx"):
            hash, _ = self.uint256_serializer.deserialize(key, key_cursor)
            wallet_tx, _ = self.wallet_tx_serializer.deserialize(value, value_cursor)
            self.txs[hash] = wallet_tx

    def _read_poolkeys(self):
        for key, key_cursor, value, value_cursor in self._read_entries("pool"):
            poolnum, = struct.unpack_from("<q", key, key_cursor)
            version, = struct.unpack_from("<I", value, 0)
            time, = struct.unpack_from("<q", value, 4)
            public_key, _ = self.varstr_serializer.deserialize(value, 12)
            self.poolkeys[poolnum] = WalletPoolKey(poolnum, version, time, public_key)
            self.poolkeys_by_public_key[public_key] = self.poolkeys[poolnum]

    def _read_wallet(self):
        self.reset_wallet()
        self._read_keys()
        self._read_crypted_keys()
        self._read_master_keys()
        self._read_names()
        self._read_txs()
        self._read_poolkeys()

    def get_keys(self):
        return self.keys

    def get_crypted_keys(self):
        return self.crypted_keys

    def get_wallet_txs(self):
        return self.txs

    def get_names(self):
        return self.names

    def get_poolkeys(self):
        return self.poolkeys

    def add_poolkey(self, poolkey):
        self.db.put(
            "\x04pool" + struct.pack("<q", poolkey.poolnum),
            struct.pack("<I", poolkey.version)
            + struct.pack("<q", poolkey.time)
            + self.varstr_serializer.serialize(poolkey.public_key),
            txn=self.dbtxn,
        )
        self.poolkeys[poolkey.poolnum] = poolkey
        self.poolkeys_by_public_key[poolkey.public_key] = self.poolkeys[poolkey.poolnum]

    def set_label(self, address, label):
        self.names[address] = WalletName(label, address)
        address = self.varstr_serializer.serialize(address.to_base58addr())
        name = self.varstr_serializer.serialize(label)
        self.db.put("\x04name" + address, name, txn=self.dbtxn)

    def add_name(self, wallet_name):
        pass

    def add_keypair(self, wallet_keypair):
        pass

    def set_transaction(self, hashtx, wallet_tx):
        self.txs[hashtx] = wallet_tx
        key = self.uint256_serializer.serialize(hashtx)
        value = self.wallet_tx_serializer.serialize(wallet_tx)
        self.db.put("\x02tx" + key, value, txn=self.dbtxn)

    def get_transaction(self, hashtx):
        return self.txs[hashtx]

    def del_transaction(self, hashtx):
        del self.txs[hashtx]
        self.db.delete("\x02tx" + self.uint256_serializer.serialize(hashtx), txn=self.dbtxn)

    def del_poolkey(self, num):
        del self.poolkeys[num]
        self.db.delete("\x04pool" + struct.pack("<I", num))

    def add_master_key(self, master_key):
        id = max(self.master_keys.keys() + [0]) + 1
        key = "\x04mkey" + struct.pack("<I", id)
        value = self.master_key_serializer.serialize(master_key)
        self.db.put(key, value, txn=self.dbtxn)
        self.master_keys[id] = master_key

    def add_crypted_key(self, public_key, crypted_secret):
        self.db.put(
            "\x04ckey" + self.varstr_serializer.serialize(public_key),
            self.varstr_serializer.serialize(crypted_secret),
            txn=self.dbtxn,
        )
        self.crypted_keys[public_key] = crypted_secret

    def get_master_keys(self):
        return self.master_keys

    def get_version(self):
        return struct.unpack("<I", self.db["\x07version"])[0]

    def set_version(self, version):
        self.db["\x07version"] = struct.pack("<I", version)

    """ Return wallet's BlockLocator or None if not found """

    def get_block_locator(self):
        if self.db.has_key("\x09bestblock"):
            serializer = BlockLocatorSerializer()
            block_locator, cursor = serializer.deserialize(self.db["\x09bestblock"], 0)
            return block_locator

    def set_blocklocator(self, blocklocator):
        serializer = BlockLocatorSerializer()
        self.db["\x09bestblock"] = serializer.serialize(blocklocator)

    def __str__(self):
        keys_str = "\n".join("    " + str(k) for k in self.get_keypairs())
        pool_keys_str = "\n".join("    " + str(k) for k in self.get_poolkeys())
        names_str = "\n".join("    " + str(k) for k in self.get_names())
        tx_str = "\n".join("    " + str(k) for k in self.get_wallet_txs())
        return (
            "Wallet\n  keys:\n"
            + keys_str
            + "pool:\n"
            + pool_keys_str
            + "\n  names:\n"
            + names_str
            + "\n  txs:\n"
            + tx_str
        )
Ejemplo n.º 12
0
 def test_varstr_deserialize(self):
     str, _ = VarstrSerializer().deserialize(decodehexstr("0568656c6c6f"))
     self.assertEquals(str, "hello")
Ejemplo n.º 13
0
 def test_varstr_serialize(self):
     self.assertEquals(hexstr(VarstrSerializer().serialize("hello")),
                       "0568656c6c6f")
Ejemplo n.º 14
0
 def __init__(self):
     self.serializer = ScriptSerializer()
     self.strencoder = VarstrSerializer()