def main(): UPnP.init() Chain.init() parser = ArgumentParser( usage= 'recipd.py <arguments> [<option>, ...] \ \n \ \nReciprocity Daemon - supported arguments: \ \n \ \nArgument Option Description \ \n-s <port> Service API port used by nodes (default: 8912) \ \n-n <port> Communication port used by nodes (default: 8489)' ) parser.add_argument('-s', '--service_port', type=int, default=8912, help='Service API port used by nodes (default: 8912)') parser.add_argument( '-n', '--node_port', type=int, default=8489, help='Communication port used by nodes (default: 8489)') try: arguments = parser.parse_args() handleArguments(arguments) except: parser.print_help() return
def __init__(self): super().__init__() self.type = MessageType.GETDATA self.inventory = [] self.chain = Chain.getChain() self.memoryPool = MemoryPool.getMemoryPool()
def __init__(self): super().__init__() self.type = MessageType.GETBLOCKS self.version = Config.getIntValue("BLOCK_VERSION") self.blockHashes = [] self.chain = Chain.getChain()
def getNewBlockBits(chainHeadBlock, chainHeadBlockHeight): newBlockBits = chainHeadBlock.bits if chainHeadBlockHeight > 0: blockRetargeting = getBlockRetargeting() if chainHeadBlockHeight % blockRetargeting == 0: retargetingStartBlock = chainHeadBlock retargeting = None index = 0 while index < blockRetargeting: retargetingBlockTarget = getTargetFromBits( retargetingStartBlock.bits) if retargeting == None: retargeting = retargetingBlockTarget if Config.getBoolValue('DGW3_ENABLED'): if index > 0: retargeting = (retargeting * index + retargetingBlockTarget) // (index + 1) retargetingStartBlock = Chain.getChain().getBlockByHash( retargetingStartBlock.previousHash) index += 1 blockIntervalTime = chainHeadBlock.timestamp - retargetingStartBlock.timestamp blockIntervalTime = math.ceil(blockIntervalTime) adjustedTarget = adjustTarget(retargeting, blockIntervalTime) if adjustedTarget > getTargetFromBits( Config.getIntValue('GENESIS_BLOCK_DIFFICULTY_BITS', 16)): adjustedTarget = getTargetFromBits( Config.getIntValue('GENESIS_BLOCK_DIFFICULTY_BITS', 16)) newBlockBits = getBitsFromTarget(adjustedTarget) return newBlockBits
def verifyCoinbaseMaturity(self, transaction): for txIn in transaction.inputs: coin = UXTO.getUnspentTransactionCoin(txIn.outpoint) if coin.isCoinbase(): chainHeadIndexBlock = Chain.getChain().getChainHeadIndexBlock() if Config.getIntValue( 'COINBASE_MATURITY' ) > chainHeadIndexBlock.height - coin.height: return False return True
def __init__(self, transaction, _input, output, readOnly, deploy, localTx): self.transaction = transaction self.input = _input self.output = output self.persistentStorageKey = output.address self.origin = output.address self.gasRemaining = self.transaction.gasLimit self.chainHeadBlock = Chain.getChain().getChainHeadBlock() self.chainHeadIndexBlock = Chain.getChain().getChainHeadIndexBlock() self.code = bytearray() self.data = bytearray() self.pc = None self.currOpcode = None self.stack = [] self.memory = bytearray() self.JUMPDEST = Opcodes.alias('JUMPDEST') self.readOnly = readOnly self.deploy = deploy self.localTx = localTx self.merge = False self.override = not output.hasExtScript() self.overrideAddress = None self.overrideScript = None self.overrideValue = None self.invalid = False self.logs = [] self.initialize()
def send(self): peer = Peers.getPeerByHost(self.addrRecv) if peer.lastVersionNonce == None: peer.lastVersionNonce = self.nonce Peers.addPeer(peer) else: self.nonce = peer.lastVersionNonce chainHeadBlock = Chain.getChain().getChainHeadBlock() self.chainHeadBlockHash = chainHeadBlock.hash() payload = Network.sendData(self.addrRecv, self.serialize()) message = MessageFactory.getInstance(MessageType.VERACK) message.addrFrom = self.addrRecv if message.deserialize(payload): message.onSuccess() else: peer = Peer() peer.host = self.addrRecv Peers.removePeer(peer) message.onFailure(self.sendFailure)
def blockhash(self): blockHeight = self.popAsInt() _blockHash = Chain.getChain().getBlockHashByHeight(blockHeight) self.stack.append(_blockHash)
def __init__(self): super().__init__() self.address = None self.enabled = None self.chain = Chain.getChain()
def coinbaseMaturity(height): chainHeadIndexBlock = Chain.getChain().getChainHeadIndexBlock() if Config.getIntValue( 'COINBASE_MATURITY') > chainHeadIndexBlock.height - height: return False return True
def __init__(self): super().__init__() self.type = MessageType.INV self.inventory = [] self.chain = Chain.getChain()
def validate(self, block): ''' Check syntactic correctness ''' if block.version == None or block.version != Config.getIntValue("BLOCK_VERSION"): return False if block.previousHash == None or len(block.previousHash) != Config.getIntValue('HASH_LEN'): return False if block.merkleRoot == None or len(block.merkleRoot) != Config.getIntValue('HASH_LEN'): return False if block.witnessRoot == None or len(block.witnessRoot) != Config.getIntValue('HASH_LEN'): return False if block.gasLimit == None or block.gasLimit < 0: return False if block.gasUsed == None or block.gasUsed < 0: return False if block.nonce == None or block.nonce < 0: return False if block.bits == None or block.bits < 0: return False if block.timestamp == None or block.timestamp < 0: return False blkHash = block.hash() if block.previousHash == Config.getBytesValue('GENESIS_BLOCK_PREVIOUS_HASH', False): if blkHash != Config.getBytesValue('GENESIS_BLOCK_HASH'): print('Check Genesis Block Hash:', blkHash.hex()) return False ''' Reject if duplicate of block we have in any of the three categories ''' ''' 1) blocks in the main branch the transactions in these blocks are considered at least tentatively confirmed 2) blocks on side branches off the main branch these blocks have at least tentatively lost the race to be in the main branch ''' if Chain.getChain().getBlockByHash(blkHash) != None: return False ''' 3) orphan blocks these are blocks which don't link into the main branch, normally because of a missing predecessor or nth-level predecessor ''' if OrphanManager.hasBlock(blkHash): return False if not self.verifyTransactionsNonEmpty(block): return False ''' Block hash must satisfy claimed nBits proof of work ''' if not self.validateBlockBits(block.serializeHeader(), block.bits): return False if not self.verifyFutureTimestamp(block): return False if not self.verifyInitialCoinbaseTransaction(block): return False ''' Check block gas limit ''' totalTxGasLimit = 0 for transaction in block.transactions: totalTxGasLimit += transaction.gasLimit if totalTxGasLimit > block.gasLimit: return False if block.gasUsed > block.gasLimit: return False previousBlockGasLimit = None if blkHash == Config.getBytesValue('GENESIS_BLOCK_HASH'): previousBlockGasLimit = Config.getIntValue('GENESIS_BLOCK_GAS_LIMIT') else: previousIndexBlock = Chain.getChain().getIndexBlockByHash(block.previousHash) if previousIndexBlock != None: previousBlockGasLimit = previousIndexBlock.gasLimit ''' If previousBlockGasLimit is none, block is probably an orphan. ''' if previousBlockGasLimit != None: maxBlockGasLimit = previousBlockGasLimit + (previousBlockGasLimit * (1 / 1024)) maxBlockGasLimit = math.ceil(maxBlockGasLimit) # Check block gas limit increase a max of 1 / 1024 if block.gasLimit > maxBlockGasLimit: return False ''' Check block size in bytes ''' if not self.verifyBlockSizeLimit(block): return False ''' For each transaction, apply "tx" checks 2-4 2) Make sure neither in or out lists are empty 3) Size in bytes <= TRANSACTION_SIZE_LIMIT 4) Each output value, as well as the total, must be in legal money range ''' for transaction in block.transactions: if not self.txValidator.verifyInputOutputNonEmpty(transaction): return False if not self.txValidator.verifyTransactionSizeLimit(transaction): return False if not self.txValidator.verifyAllowedOutputValueRange(transaction): return False if not self.verifyCoinbaseWitnessLength(transaction): return False if not self.verifyMaxBlockSigOps(transaction): return False if not self.verifyMerkleHash(block): return False if not self.verifyWitnessHash(block): return False ''' Check if prev block (matching prev hash) is in main branch or side branches. If not, add this to orphan blocks, then query peer we got this from for 1st missing orphan block in prev chain; done with block ''' if blkHash != Config.getBytesValue('GENESIS_BLOCK_HASH') and Chain.getChain().getBlockByHash(block.previousHash) == None: OrphanManager.addBlock(block) ''' Check that nBits value matches the difficulty rules ''' chainHeadBlock = None chainHeadBlockHeight = None if blkHash == Config.getBytesValue('GENESIS_BLOCK_HASH'): chainHeadBlock = block chainHeadBlockHeight = 0 else: chainHeadBlock = Chain.getChain().getChainHeadBlock() chainHeadIndexBlock = Chain.getChain().getChainHeadIndexBlock() chainHeadBlockHeight = chainHeadIndexBlock.height newBlockBits = Bits.getNewBlockBits(chainHeadBlock, chainHeadBlockHeight) if block.bits != newBlockBits: return False ''' Reject if timestamp is the median time of the last 11 blocks or before ''' timestamps = [] prevBlock = Chain.getChain().getBlockByHash(block.previousHash) while prevBlock != None and len(timestamps) <= 11: timestamps.append(prevBlock.timestamp) prevBlock = Chain.getChain().getBlockByHash(prevBlock.previousHash) if len(timestamps) == 11: timestamps.sort() if block.timestamp <= timestamps[5]: return False ''' For certain old blocks (i.e. on initial block download) check that hash matches known values ''' return True
def onSuccess(self, callback = None): block = CoreBlock() block.deserialize(self.block) if not Chain.getChain().addBlock(block): self.onFailure(callback)