Пример #1
0
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
Пример #2
0
    def __init__(self):
        super().__init__()
        self.type = MessageType.GETDATA
        self.inventory = []

        self.chain = Chain.getChain()
        self.memoryPool = MemoryPool.getMemoryPool()
Пример #3
0
    def __init__(self):
        super().__init__()
        self.type = MessageType.GETBLOCKS
        self.version = Config.getIntValue("BLOCK_VERSION")
        self.blockHashes = []

        self.chain = Chain.getChain()
Пример #4
0
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
Пример #5
0
 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
Пример #6
0
    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()
Пример #7
0
    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)
Пример #8
0
 def blockhash(self):
     blockHeight = self.popAsInt()
     _blockHash = Chain.getChain().getBlockHashByHeight(blockHeight)
     self.stack.append(_blockHash)
Пример #9
0
 def __init__(self):
     super().__init__()
     self.address = None
     self.enabled = None
     
     self.chain = Chain.getChain()
Пример #10
0
def coinbaseMaturity(height):
    chainHeadIndexBlock = Chain.getChain().getChainHeadIndexBlock()
    if Config.getIntValue(
            'COINBASE_MATURITY') > chainHeadIndexBlock.height - height:
        return False
    return True
Пример #11
0
    def __init__(self):
        super().__init__()
        self.type = MessageType.INV
        self.inventory = []

        self.chain = Chain.getChain()
Пример #12
0
    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
Пример #13
0
 def onSuccess(self, callback = None):
     block = CoreBlock()
     block.deserialize(self.block)
     if not Chain.getChain().addBlock(block):
         self.onFailure(callback)