예제 #1
0
 def get_wallet(self, address):
     if isinstance(address, str):
         address = address.encode()
     if self.wallets_db.exists(address):
         return util.decodeMsg(self.wallets_db.get(address),
                               decoder=wallet.decodeWallet)
     return None
예제 #2
0
def handleTX(msg):
    # print("Handling tx")
    txMsg = decodeMsg(msg)
    tx = transaction.decodeTX(txMsg['tx'])
    miner.add_txs([tx])

    # broadcast the new TX to all nodes.
    # NOTE: This will not cause an infinite broadcast loop,
    # because only txs nodes haven't seen get broadcast
    broadcast_tx(tx, exclude=[txMsg['addrFrom']])
예제 #3
0
def handleVersion(msg):
    # print("Handling version")
    version = decodeMsg(msg)
    print(version)
    localBestHeight = Blockchain().getBestHeight()
    remoteBestHeight = version['bestHeight']
    if localBestHeight < remoteBestHeight:
        sendGetBlocks(version['addrFrom'])
    elif localBestHeight > remoteBestHeight:
        sendVersion(version['addrFrom'])

    if version['addrFrom'] not in knownNodes:
        knownNodes.append(version['addrFrom'])
        sendAddr(version['addrFrom'])
예제 #4
0
def handleGetData(msg):
    getdata = decodeMsg(msg)
    # print("Handling getdata from %s" % getdata['addrFrom'])

    if getdata['type'] == b'block':
        block = Blockchain().getBlock(getdata['id'])
        if not block: return

        sendBlock(getdata['addrFrom'], block)

    elif getdata['type'] == b'tx':
        txID = getdata['id']
        if txID not in miner.mempool: return

        sendTX(getdata['addrFrom'], miner.mempool[txID])
예제 #5
0
    def findSpendableOutputs(self, pubKeyHash, amount):
        outputDict = {}
        accumulated = 0

        for txId, encodedOutputs in self.utxos_db.iter_items():
            unspentOutputs = util.decodeMsg(encodedOutputs, decoder=txout.decodeTXOutput)
            for txOutput in unspentOutputs:
                if txOutput.isLockedWithKey(pubKeyHash) and accumulated < amount:
                    if txId not in outputDict:
                        outputDict[txId] = {}
                    if txOutput.idx in outputDict[txId]:
                        print("Collision! TXOutput already accounted for.")
                    else:
                        outputDict[txId][txOutput.idx] = txOutput
                        accumulated += txOutput.value
        return accumulated, outputDict
예제 #6
0
def handleInv(msg):
    inv = decodeMsg(msg)
    # print("Handling inv with %d %ss from %s" % (len(inv['items']), toStr(inv['type']), inv['addrFrom']))

    if len(inv['items']) == 0: return

    if inv['type'] == b'block':
        addrFrom = inv['addrFrom']
        if addrFrom not in blocksInTransit:
            blocksInTransit[addrFrom] = []
        blocksInTransit[addrFrom].extend(inv['items'])
        hash = inv['items'][0]
        sendGetData(addrFrom, b'block', hash)
    elif inv['type'] == b'tx':
        txID = inv['items'][0]
        if txID not in miner.mempool:
            sendGetData(inv['addrFrom'], b'tx', txID)
예제 #7
0
    def update(self, block):
        with self.utxos_db.snapshot() as s, self.utxo_db.write_batch() as wb:
            for tx in block.transactions:
                # coinbase txs don't have inputs, duh
                if not tx.isCoinbase():
                    # for each input, remove the output that it spends from the UTXO set
                    for txInput in tx.vin:
                        txOutputs = util.decodeMsg(s.get(txInput.txId))
                        updatedOutputs = [txOutput for txOutput in txOutputs if txOutput[b'idx'] != txInput.outIdx]

                        if len(updatedOutputs) == 0:
                            wb.delete(txInput.txId)
                        else:
                            encodedOutputs = util.encodeMsg(updatedOutputs)
                            wb.put(txInput.txId, encodedOutputs)

                # add new outputs to the UTXO set
                encodedNewOutputs = util.encodeMsg(list(tx.outDict.values()), encoder=txout.encodeTXOutput)
                wb.put(tx.id, encodedNewOutputs)
예제 #8
0
def handleBlock(msg):
    blc = decodeMsg(msg)
    # print("Handling block from %s" % blc['addrFrom'])
    block = decodeBlock(blc['block'])
    addrFrom = blc['addrFrom']

    if addrFrom in blocksInTransit:
        try:
            blocksInTransit[addrFrom].remove(block.hash)
        except ValueError:
            print("Got block that wasn't requested.")
            return
    else:
        print("Got block that wasn't requested")
        return

    Blockchain().addBlock(block)
    print("Added block %s" % block.hash.hex()[:14])

    if len(blocksInTransit[addrFrom]) > 0:
        sendGetData(addrFrom, b'block', blocksInTransit[addrFrom][0])
    else:
        del blocksInTransit[addrFrom]
        UTXOSet().reindex()
예제 #9
0
 def get_unspent_outputs(self, tx_id):
     encoded_outs = self.utxos_db.get(tx_id)
     if encoded_outs == b'':
         return []
     return util.decodeMsg(encoded_outs, decoder=txout.decodeTXOutput)
예제 #10
0
 def find_utxo(self, pub_key_hash):
     utxo = []
     for encoded_outs in self.utxos_db.iter_values():
         unspent_outs = util.decodeMsg(encoded_outs, decoder=txout.decodeTXOutput)
         utxo.extend([tx_out for tx_out in unspent_outs if tx_out.isLockedWithKey(pub_key_hash)])
     return utxo
예제 #11
0
 def getTip(self):
     if not self.blocks_db.exists(b'l'):
         return None
     encodedBlock = self.blocks_db.get(self.blocks_db.get(b'l'))
     return block.decodeBlock(util.decodeMsg(encodedBlock))
예제 #12
0
 def getBlock(self, hash):
     if not self.blocks_db.exists(hash):
         return None
     return block.decodeBlock(util.decodeMsg(self.blocks_db.get(hash)))
예제 #13
0
 def next(self):
     encodedBlock = self.blocks_db.get(self.currentHash)
     currentBlock = block.decodeBlock(util.decodeMsg(encodedBlock))
     self.currentHash = currentBlock.prevHash
     return currentBlock
예제 #14
0
def handleAddr(msg):
    # print("Handling addr")
    addresses = decodeMsg(msg)
    knownNodes.extend(addresses['addrList'])
    print("There are now %d peers" % len(knownNodes))
    requestBlocks()
예제 #15
0
def handleGetBlocks(msg):
    getblocks = decodeMsg(msg)
    # print("Handling getblocks from %s" % getblocks['addrFrom'])
    sendInv(getblocks['addrFrom'], b'block', Blockchain().getBlockHashes())