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
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']])
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'])
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])
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
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)
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)
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()
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)
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
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))
def getBlock(self, hash): if not self.blocks_db.exists(hash): return None return block.decodeBlock(util.decodeMsg(self.blocks_db.get(hash)))
def next(self): encodedBlock = self.blocks_db.get(self.currentHash) currentBlock = block.decodeBlock(util.decodeMsg(encodedBlock)) self.currentHash = currentBlock.prevHash return currentBlock
def handleAddr(msg): # print("Handling addr") addresses = decodeMsg(msg) knownNodes.extend(addresses['addrList']) print("There are now %d peers" % len(knownNodes)) requestBlocks()
def handleGetBlocks(msg): getblocks = decodeMsg(msg) # print("Handling getblocks from %s" % getblocks['addrFrom']) sendInv(getblocks['addrFrom'], b'block', Blockchain().getBlockHashes())