Beispiel #1
0
 def validate_uncles(self):
     if utils.sha3(rlp.encode(self.uncles)) != self.uncles_hash:
         return False
     # Check uncle validity
     ancestor_chain = [self]
     # Uncle can have a block from 2-7 blocks ago as its parent
     for i in [1, 2, 3, 4, 5, 6, 7]:
         if ancestor_chain[-1].number > 0:
             ancestor_chain.append(ancestor_chain[-1].get_parent())
     ineligible = []
     # Uncles of this block cannot be direct ancestors and cannot also
     # be uncles included 1-6 blocks ago
     for ancestor in ancestor_chain[1:]:
         ineligible.extend(ancestor.uncles)
     ineligible.extend([b.list_header() for b in ancestor_chain])
     eligible_ancestor_hashes = [x.hash for x in ancestor_chain[2:]]
     for uncle in self.uncles:
         if not check_header_pow(uncle):
             return False
         # uncle's parent cannot be the block's own parent
         prevhash = uncle[block_structure_rev['prevhash'][0]]
         if prevhash not in eligible_ancestor_hashes:
             logger.debug("%r: Uncle does not have a valid ancestor", self)
             return False
         if uncle in ineligible:
             logger.debug("%r: Duplicate uncle %r", self, utils.sha3(rlp.encode(uncle)).encode('hex'))
             return False
         ineligible.append(uncle)
     return True
Beispiel #2
0
def check_header_pow(header):
    assert len(header[-1]) == 32
    rlp_Hn = rlp.encode(header[:-1])
    nonce = header[-1]
    diff = utils.decoders['int'](header[block_structure_rev['difficulty'][0]])
    h = utils.sha3(utils.sha3(rlp_Hn) + nonce)
    return utils.big_endian_to_int(h) < 2 ** 256 / diff
Beispiel #3
0
    def mine(self, steps=1000):
        """
        It is formally defined as PoW: PoW(H, n) = BE(SHA3(SHA3(RLP(Hn)) o n))
        where:
        RLP(Hn) is the RLP encoding of the block header H, not including the
            final nonce component;
        SHA3 is the SHA3 hash function accepting an arbitrary length series of
            bytes and evaluating to a series of 32 bytes (i.e. 256-bit);
        n is the nonce, a series of 32 bytes;
        o is the series concatenation operator;
        BE(X) evaluates to the value equal to X when interpreted as a
            big-endian-encoded integer.
        """

        nonce_bin_prefix = '\x00' * (32 - len(struct.pack('>q', 0)))
        target = 2 ** 256 / self.block.difficulty
        rlp_Hn = self.block.serialize_header_without_nonce()

        for nonce in range(self.nonce, self.nonce + steps):
            nonce_bin = nonce_bin_prefix + struct.pack('>q', nonce)
            # BE(SHA3(SHA3(RLP(Hn)) o n))
            h = utils.sha3(utils.sha3(rlp_Hn) + nonce_bin)
            l256 = utils.big_endian_to_int(h)
            if l256 < target:
                self.block.nonce = nonce_bin
                assert self.block.check_proof_of_work(self.block.nonce) is True
                assert self.block.get_parent()
                logger.debug(
                    'Nonce found %d %r', nonce, self.block)
                return self.block

        self.nonce = nonce
        return False
Beispiel #4
0
 def check_proof_of_work(self, nonce):
     assert len(nonce) == 32
     rlp_Hn = self.serialize_header_without_nonce()
     # BE(SHA3(SHA3(RLP(Hn)) o n))
     h = utils.sha3(utils.sha3(rlp_Hn) + nonce)
     l256 = utils.big_endian_to_int(h)
     return l256 < 2 ** 256 / self.difficulty
Beispiel #5
0
def create_contract(block,tx,msg):
    oldroot = block.state.root
    senderstate = block.state.get(msg.sender) or ['','','','']
    recvstate = ['','',sha3(msg.data),'']
    recvaddr = sha3(rlp.encode([msg.sender,senderstate[NONCE_INDEX]]))[12:]
    code = msg.data
    statedb.put(sha3(msg.data),msg.data)
    compustate = Compustate(gas=msg.gas)
    # Not enough vaue to send, instaquit
    if decode_int(senderstate[BALANCE_INDEX]) < msg.value:
        recvstate[2] = []
        block.state.update(recvaddr,recvstate)
        return recvaddr, compustate.gas
    # Transfer value and update nonce
    senderstate[BALANCE_INDEX] = encode_int(decode_int(senderstate[BALANCE_INDEX])-msg.value)
    senderstate[NONCE_INDEX] = encode_int(decode_int(senderstate[NONCE_INDEX])+1)
    recvstate[BALANCE_INDEX] = encode_int(decode_int(senderstate[BALANCE_INDEX])+msg.value)
    block.state.update(msg.sender.decode('hex'),senderstate)
    block.state.update(recvaddr,recvstate)
    # Temporary pre-POC5: don't do the code/init thing
    return recvaddr, compustate.gas
    # Main loop
    while 1:
        o = apply_op(block,tx,msg,msg.data,compustate.op)
        if o is not None:
            if o == OUT_OF_GAS:
                block.state.root = oldroot
                return 0, 0
            else:
                recvstate = block.state.get(recvaddr)
                recvstate[CODE_INDEX] = sha3(map(chr,o))
                statedb.put(sha3(map(chr,o)),map(chr,o))
                block.state.update(recvaddr,recvstate)
                return recvaddr, recvstate
Beispiel #6
0
def check_header_pow(header):
    assert len(header[-1]) == 32
    rlp_Hn = rlp.encode(header[:-1])
    nonce = header[-1]
    diff = utils.decoders['int'](header[block_structure_rev['difficulty'][0]])
    h = utils.sha3(utils.sha3(rlp_Hn) + nonce)
    return utils.big_endian_to_int(h) < 2**256 / diff
Beispiel #7
0
    def to_dict(self, with_state=False, full_transactions=False,
                      with_storage_roots=False, with_uncles=False):
        """
        serializes the block
        with_state:             include state for all accounts
        full_transactions:      include serialized tx (hashes otherwise)
        with_uncles:            include uncle hashes
        """
        b = {}
        for name, typ, default in block_structure:
            b[name] = utils.printers[typ](getattr(self, name))
        txlist = []
        for i in range(self.transaction_count):
            tx_rlp = self.transactions.get(rlp.encode(utils.encode_int(i)))
            tx, msr, gas = rlp.decode(tx_rlp)
            if full_transactions:
                txjson = transactions.Transaction.create(tx).to_dict()
            else:
                txjson = utils.sha3(rlp.descend(tx_rlp, 0)).encode('hex')  # tx hash
            txlist.append({
                "tx": txjson,
                "medstate": msr.encode('hex'),
                "gas": str(utils.decode_int(gas))
            })
        b["transactions"] = txlist
        if with_state:
            state_dump = {}
            for address, v in self.state.to_dict().iteritems():
                state_dump[address.encode('hex')] = \
                    self.account_to_dict(address, with_storage_roots)
            b['state'] = state_dump
        if with_uncles:
            b['uncles'] = [utils.sha3(rlp.encode(u)).encode('hex') for u in self.uncles]

        return b
Beispiel #8
0
 def mk_blank_acct(self):
     if not hasattr(self, '_blank_acct'):
         codehash = utils.sha3('')
         self.state.db.put(utils.sha3(''), '')
         self._blank_acct = [utils.encode_int(0),
                             utils.encode_int(0),
                             trie.BLANK_ROOT,
                             codehash]
     return self._blank_acct[:]
Beispiel #9
0
 def mk_blank_acct(self):
     if not hasattr(self, '_blank_acct'):
         codehash = utils.sha3('')
         self.state.db.put(utils.sha3(''), '')
         self._blank_acct = [utils.encode_int(0),
                             utils.encode_int(0),
                             trie.BLANK_ROOT,
                             codehash]
     return self._blank_acct[:]
Beispiel #10
0
 def serialize(self):
     txlist = [x.serialize() for x in self.transactions]
     header = [
         encode_int(self.number), self.prevhash,
         sha3(rlp.encode(self.uncles)),
         self.coinbase.decode('hex'), self.state.root,
         sha3(rlp.encode(txlist)),
         encode_int(self.difficulty),
         encode_int(self.timestamp), self.extradata,
         encode_int(self.nonce)
     ]
     return rlp.encode([header, txlist, self.uncles])
Beispiel #11
0
 def serialize(self):
     txlist = [x.serialize() for x in self.transactions]
     header = [encode_int(self.number),
               self.prevhash,
               sha3(rlp.encode(self.uncles)),
               self.coinbase.decode('hex'),
               self.state.root,
               sha3(rlp.encode(txlist)),
               encode_int(self.difficulty),
               encode_int(self.timestamp),
               self.extradata,
               encode_int(self.nonce)]
     return rlp.encode([header, txlist, self.uncles])
Beispiel #12
0
def create_contract(block,tx,msg):
    snapshot = block.snapshot()
    sender = msg.sender.decode('hex') if len(msg.sender) == 40 else msg.sender
    nonce = encode_int(block.get_nonce(msg.sender))
    recvaddr = sha3(rlp.encode([sender,nonce]))[12:]
    code = msg.data
    # Transfer value, instaquit if not enough
    block.delta_balance(recvaddr,msg.value)
    o = block.delta_balance(msg.sender,msg.value)
    if not o:
        return 0, msg.gas
    block.set_code(recvaddr,msg.data)
    compustate = Compustate(gas=msg.gas)
    # Temporary pre-POC5: don't do the code/init thing
    return recvaddr, compustate.gas
    # Main loop
    while 1:
        o = apply_op(block,tx,msg,msg.data,compustate.op)
        if o is not None:
            if o == OUT_OF_GAS:
                block.state.root = oldroot
                return 0, 0
            else:
                block.set_code(''.join(map(chr,o)))
                return recvaddr, compustate.gas
Beispiel #13
0
 def sign(self, privkey):
     assert not self.signature
     assert isinstance(privkey, bytes) and len(privkey) == 32
     h = sha3(_encode_optimized(self.serialize()))
     self.signature = c_ecdsa_sign_compact(h, privkey)
     assert len(self.signature) == 65
     return self
Beispiel #14
0
 def send(self, sender, host_port, data):
     print 'in send unreliable', self.network.counter, self.network.counter % self.droprate
     if self.network.counter % self.droprate:
         self.network.send(sender, host_port, data)
     else:
         self.network.track_send(sender, host_port, data)
         print('dropped data {}'.format(pex(sha3(data))))
Beispiel #15
0
 def validate_uncles(self):
     if utils.sha3rlp(self.uncles) != self.uncles_hash:
         return False
     # Check uncle validity
     ancestor_chain = [a for a in self.get_ancestor_list(MAX_UNCLE_DEPTH + 1) if a]
     ineligible = []
     # Uncles of this block cannot be direct ancestors and cannot also
     # be uncles included 1-6 blocks ago
     for ancestor in ancestor_chain[1:]:
         ineligible.extend(ancestor.uncles)
     ineligible.extend([b.list_header() for b in ancestor_chain])
     eligible_ancestor_hashes = [x.hash for x in ancestor_chain[2:]]
     for uncle in self.uncles:
         if not check_header_pow(uncle):
             return False
         prevhash = uncle[block_structure_rev['prevhash'][0]]
         if prevhash not in eligible_ancestor_hashes:
             log.error("Uncle does not have a valid ancestor", block=self)
             return False
         if uncle in ineligible:
             log.error("Duplicate uncle", block=self, uncle=utils.sha3(
                 rlp.encode(uncle)).encode('hex'))
             return False
         ineligible.append(uncle)
     return True
Beispiel #16
0
 def validate_uncles(self):
     if utils.sha3rlp(self.uncles) != self.uncles_hash:
         return False
     # Check uncle validity
     ancestor_chain = self.get_ancestor_list(MAX_UNCLE_DEPTH + 1)
     ineligible = []
     # Uncles of this block cannot be direct ancestors and cannot also
     # be uncles included 1-6 blocks ago
     for ancestor in ancestor_chain[1:]:
         ineligible.extend(ancestor.uncles)
     ineligible.extend([b.list_header() for b in ancestor_chain])
     eligible_ancestor_hashes = [x.hash for x in ancestor_chain[2:]]
     for uncle in self.uncles:
         if not check_header_pow(uncle):
             return False
         prevhash = uncle[block_structure_rev['prevhash'][0]]
         if prevhash not in eligible_ancestor_hashes:
             log.error("Uncle does not have a valid ancestor", block=self)
             return False
         if uncle in ineligible:
             log.error("Duplicate uncle", block=self, uncle=utils.sha3(
                 rlp.encode(uncle)).encode('hex'))
             return False
         ineligible.append(uncle)
     return True
Beispiel #17
0
def remote_blocks_received_handler(sender, block_lst, peer, **kwargs):
    logger.debug("received %d remote blocks", len(block_lst))

    old_head = chain_manager.head
    # assuming chain order w/ newest block first
    for block_data in reversed(block_lst):
        try:
            block = blocks.Block.deserialize(rlp.encode(block_data))
        except blocks.UnknownParentException:
            # no way to ask peers for older parts of chain
            bhash = utils.sha3(rlp.encode(block_data)).encode('hex')[:4]
            phash = block_data[0][0].encode('hex')[:4]
            number = utils.decode_int(block_data[0][6])
            logger.debug('Block(#%d %s %s) with unknown parent, requesting ...',
                         number, bhash, phash.encode('hex')[:4])
            chain_manager.synchronize_blockchain()
            break
        if block.hash in chain_manager:
            logger.debug('Known %r', block)
        else:
            if block.has_parent():
                # add block & set HEAD if it's longest chain
                success = chain_manager.add_block(block)
                if success:
                    logger.debug('Added %r', block)
            else:
                logger.debug('Orphant %r', block)
    if chain_manager.head != old_head:
        chain_manager.synchronize_blockchain()
Beispiel #18
0
def create_contract(block, tx, msg):
    snapshot = block.snapshot()
    sender = msg.sender.decode('hex') if len(msg.sender) == 40 else msg.sender
    nonce = encode_int(block.get_nonce(msg.sender))
    recvaddr = sha3(rlp.encode([sender, nonce]))[12:]
    code = msg.data
    # Transfer value, instaquit if not enough
    block.delta_balance(recvaddr, msg.value)
    o = block.delta_balance(msg.sender, msg.value)
    if not o:
        return 0, msg.gas
    block.set_code(recvaddr, msg.data)
    compustate = Compustate(gas=msg.gas)
    # Temporary pre-POC5: don't do the code/init thing
    return recvaddr, compustate.gas
    # Main loop
    while 1:
        o = apply_op(block, tx, msg, msg.data, compustate.op)
        if o is not None:
            if o == OUT_OF_GAS:
                block.state.root = oldroot
                return 0, 0
            else:
                block.set_code(''.join(map(chr, o)))
                return recvaddr, compustate.gas
Beispiel #19
0
def create_contract(block, tx, msg):
    snapshot = block.snapshot()

    sender = msg.sender.decode('hex') if len(msg.sender) == 40 else msg.sender
    nonce = utils.encode_int(block.get_nonce(msg.sender))
    recvaddr = utils.sha3(rlp.encode([sender, nonce]))[12:]
    assert not block.get_code(recvaddr)
    msg.to = recvaddr
    block.increment_nonce(msg.sender)
    # Transfer value, instaquit if not enough
    o = block.transfer_value(msg.sender, msg.to, msg.value)
    if not o:
        return 0, msg.gas
    compustate = Compustate(gas=msg.gas)
    # Main loop
    while 1:
        o = apply_op(block, tx, msg, msg.data, compustate)
        if o is not None:
            if o == OUT_OF_GAS:
                block.revert(snapshot)
                return 0, 0, []
            else:
                for s in block.suicides:
                    block.state.delete(utils.encode_addr(s))
                block.set_code(recvaddr, ''.join(map(chr, o)))
                return recvaddr, compustate.gas, o
Beispiel #20
0
def remote_blocks_received_handler(sender, block_lst, peer, **kwargs):
    logger.debug("received %d remote blocks", len(block_lst))

    old_head = chain_manager.head
    # assuming chain order w/ newest block first
    for block_data in reversed(block_lst):
        try:
            block = blocks.Block.deserialize(rlp.encode(block_data))
        except blocks.UnknownParentException:
            # no way to ask peers for older parts of chain
            bhash = utils.sha3(rlp.encode(block_data)).encode('hex')[:4]
            phash = block_data[0][0].encode('hex')[:4]
            number = utils.decode_int(block_data[0][6])
            if phash == blocks.GENESIS_PREVHASH:
                logger.debug('Incompatible Genesis %r', block)
                peer.send_Disconnect(reason='Wrong genesis block')
            else:
                logger.debug(
                    'Block(#%d %s %s) with unknown parent, requesting ...',
                    number, bhash,
                    phash.encode('hex')[:4])
                chain_manager.synchronize_blockchain()
            break
        if block.hash in chain_manager:
            logger.debug('Known %r', block)
        else:
            if block.has_parent():
                # add block & set HEAD if it's longest chain
                success = chain_manager.add_block(block)
                if success:
                    logger.debug('Added %r', block)
            else:
                logger.debug('Orphant %r', block)
    if chain_manager.head != old_head:
        chain_manager.synchronize_blockchain()
Beispiel #21
0
 def to_dict(self, with_state=False, full_transactions=False):
     """
     serializes the block
     with_state:             include state for all accounts
     full_transactions:      include serialized tx (hashes otherwise)
     """
     self.commit_state()
     b = {}
     for name, typ, default in block_structure:
         b[name] = utils.printers[typ](getattr(self, name))
     txlist = []
     for i in range(self.transaction_count):
         tx_rlp = self.transactions.get(rlp.encode(utils.encode_int(i)))
         tx, msr, gas = rlp.decode(tx_rlp)
         if full_transactions:
             txjson = transactions.Transaction.create(tx).to_dict()
         else:
             txjson = utils.sha3(rlp.descend(tx_rlp,
                                             0)).encode('hex')  # tx hash
         txlist.append({
             "tx": txjson,
             "medstate": msr.encode('hex'),
             "gas": str(utils.decode_int(gas))
         })
     b["transactions"] = txlist
     if with_state:
         state_dump = {}
         for address, v in self.state.to_dict().iteritems():
             state_dump[address.encode('hex')] = self.account_to_dict(
                 address)
         b['state'] = state_dump
     return b
Beispiel #22
0
    def send(self, receiver_address, msg):
        assert isaddress(receiver_address)
        assert not isinstance(msg, (Ack, BaseError)), msg
        log.info("SENDING {} > {} : {}".format(pex(self.raiden.address),
                                               pex(receiver_address), msg))
        host_port = self.discovery.get(receiver_address)
        data = msg.encode()
        msghash = sha3(data)
        self.tries[msghash] = self.max_tries
        log.debug("MSGHASH SENT", msghash=pex(msghash))

        assert len(data) < self.max_message_size

        def repeater():
            while self.tries.get(msghash, 0) > 0:
                if not self.repeat_messages and self.tries[msghash] < self.max_tries:
                    raise Exception(
                        "DEACTIVATED MSG resents {} {}".format(pex(receiver_address), msg))
                self.tries[msghash] -= 1
                self.transport.send(self.raiden, host_port, data)
                gevent.sleep(self.try_interval)

            # Each sent msg must be acked. When msg is acked its hash is removed from self.tries
            if msghash in self.tries:
                assert False, "Node does not reply, fixme suspend node"

        gevent.spawn(repeater)
Beispiel #23
0
    def send(self, receiver_address, msg):
        assert isaddress(receiver_address)
        assert not isinstance(msg, (Ack, BaseError)), msg
        log.info("SENDING {} > {} : {}".format(pex(self.raiden.address),
                                               pex(receiver_address), msg))
        host_port = self.discovery.get(receiver_address)
        data = msg.encode()
        msghash = sha3(data)
        self.tries[msghash] = self.max_tries
        log.debug("MSGHASH SENT", msghash=pex(msghash))

        assert len(data) < self.max_message_size

        def repeater():
            while self.tries.get(msghash, 0) > 0:
                if not self.repeat_messages and self.tries[
                        msghash] < self.max_tries:
                    raise Exception("DEACTIVATED MSG resents {} {}".format(
                        pex(receiver_address), msg))
                self.tries[msghash] -= 1
                self.transport.send(self.raiden, host_port, data)
                gevent.sleep(self.try_interval)

            # Each sent msg must be acked. When msg is acked its hash is removed from self.tries
            if msghash in self.tries:
                assert False, "Node does not reply, fixme suspend node"

        gevent.spawn(repeater)
Beispiel #24
0
 def get_root_hash(self):
     if self.root_node == BLANK_NODE:
         return BLANK_ROOT
     assert isinstance(self.root_node, list)
     val = rlp.encode(self.root_node)
     key = utils.sha3(val)
     self.db.put(key, val)
     return key
Beispiel #25
0
 def __init__(self, rlpdata):
     self.rlpdata = rlpdata
     self.hash = utils.sha3(rlpdata)
     header_args, transaction_list, uncles = rlp.decode(rlpdata)
     self.transaction_list = transaction_list  # rlp encoded transactions
     self.uncles = uncles
     for i, (name, typ, default) in enumerate(block_structure):
         setattr(self, name, utils.decoders[typ](header_args[i]))
Beispiel #26
0
    def _rlp_encode(self, node):
        rlpnode = rlp.encode(node)
        if len(rlpnode) < 32:
            return node

        hashkey = sha3(rlpnode)
        self.db.put(hashkey, rlpnode)
        return hashkey
Beispiel #27
0
def genesis(initial_alloc={}):
    # https://ethereum.etherpad.mozilla.org/11
    block = Block(prevhash="\x00" * 32, coinbase="0" * 40,
                  difficulty=2 ** 22, nonce=sha3(chr(42)),
                  gas_limit=10 ** 6)
    for addr in initial_alloc:
        block.set_balance(addr, initial_alloc[addr])
    return block
Beispiel #28
0
 def get_root_hash(self):
     if self.root_node == BLANK_NODE:
         return BLANK_ROOT
     assert isinstance(self.root_node, list)
     val = rlp.encode(self.root_node)
     key = utils.sha3(val)
     self.db.put(key, val)
     return key
Beispiel #29
0
 def list_header(self, exclude=[]):
     self.uncles_hash = utils.sha3(rlp.encode(self.uncles))
     header = []
     for name, typ, default in block_structure:
         # print name, typ, default , getattr(self, name)
         if name not in exclude:
             header.append(utils.encoders[typ](getattr(self, name)))
     return header
Beispiel #30
0
 def __init__(self, rlpdata):
     self.rlpdata = rlpdata
     self.hash = utils.sha3(rlpdata)
     header_args, transaction_list, uncles = rlp.decode(rlpdata)
     self.transaction_list = transaction_list  # rlp encoded transactions
     self.uncles = uncles
     for i, (name, typ, default) in enumerate(block_structure):
         setattr(self, name, utils.decoders[typ](header_args[i]))
Beispiel #31
0
    def _rlp_encode(self, node):
        rlpnode = rlp.encode(node)
        if len(rlpnode) < 32:
            return node

        hashkey = sha3(rlpnode)
        self.db.put(hashkey, rlpnode)
        return hashkey
Beispiel #32
0
    def sign(self, key, network_id=None):
        if network_id is None:
            rawhash = sha3(rlp.encode(self, UnsignedBlock))
        else:
            assert 1 <= network_id < 2**63 - 18
            rlpdata = rlp.encode(
                rlp.infer_sedes(self).serialize(self)[:-3] +
                [network_id, b'', b''])
            rawhash = sha3(rlpdata)

        key = normalize_key(key)
        self.v, self.r, self.s = ecsign(rawhash, key)
        if network_id is not None:
            self.v += 8 + network_id * 2

        self._signer = privtoaddr(key)
        return self
Beispiel #33
0
 def transfer(self, amount, target, hashlock=None, secret=None):
     if target in self.assetmanager.channels and not hashlock:
         # direct connection
         channel = self.assetmanager.channels[target]
         transfer = channel.create_transfer(amount, secret=secret)
         self.raiden.sign(transfer)
         channel.register_transfer(transfer)
         self.raiden.protocol.send(transfer.recipient, transfer)
     else:
         if not (hashlock or secret):
             secret = sha3(hex(random.getrandbits(256)))
             hashlock = sha3(secret)
         # initiate mediated transfer
         t = TransferTask(self, amount, target, hashlock,
                          expiration=None, originating_transfer=None, secret=secret)
         t.start()
         t.join()
Beispiel #34
0
 def list_header(self, exclude=[]):
     self.uncles_hash = utils.sha3(rlp.encode(self.uncles))
     header = []
     for name, typ, default in block_structure:
         # print name, typ, default , getattr(self, name)
         if name not in exclude:
             header.append(utils.encoders[typ](getattr(self, name)))
     return header
Beispiel #35
0
    def deserialize_child(self, rlpdata):
        """
        deserialization w/ replaying transactions
        """
        header_args, transaction_list, uncles = rlp.decode(rlpdata)
        assert len(header_args) == len(block_structure)
        kargs = dict(transaction_list=transaction_list, uncles=uncles)
        # Deserialize all properties
        for i, (name, typ, default) in enumerate(block_structure):
            kargs[name] = utils.decoders[typ](header_args[i])

        block = Block.init_from_parent(self,
                                       kargs['coinbase'],
                                       extra_data=kargs['extra_data'],
                                       timestamp=kargs['timestamp'],
                                       uncles=uncles)

        # replay transactions
        for tx_lst_serialized, _state_root, _gas_used_encoded in \
                transaction_list:
            tx = transactions.Transaction.create(tx_lst_serialized)
            #            logger.debug('state:\n%s', utils.dump_state(block.state))
            #            logger.debug('applying %r', tx)
            success, output = processblock.apply_transaction(block, tx)
            #block.add_transaction_to_list(tx) # < this is done by processblock
            #            logger.debug('state:\n%s', utils.dump_state(block.state))
            logger.debug('d %s %s', _gas_used_encoded, block.gas_used)
            assert utils.decode_int(_gas_used_encoded) == block.gas_used, \
                "Gas mismatch (ours %d, theirs %d) on block: %r" % \
                (block.gas_used, _gas_used_encoded, block.to_dict(False, True, True))
            assert _state_root == block.state.root_hash, \
                "State root mismatch (ours %r theirs %r) on block: %r" % \
                (block.state.root_hash.encode('hex'),
                 _state_root.encode('hex'),
                 block.to_dict(False, True, True))

        block.finalize()

        block.uncles_hash = kargs['uncles_hash']
        block.nonce = kargs['nonce']
        block.min_gas_price = kargs['min_gas_price']

        # checks
        assert block.prevhash == self.hash

        assert block.gas_used == kargs['gas_used']
        assert block.gas_limit == kargs['gas_limit']
        assert block.timestamp == kargs['timestamp']
        assert block.difficulty == kargs['difficulty']
        assert block.number == kargs['number']
        assert block.extra_data == kargs['extra_data']
        assert utils.sha3(rlp.encode(block.uncles)) == kargs['uncles_hash']

        assert block.tx_list_root == kargs['tx_list_root']
        assert block.state.root_hash == kargs['state_root'], (
            block.state.root_hash, kargs['state_root'])

        return block
Beispiel #36
0
    def to_dict(self,
                with_state=False,
                full_transactions=False,
                with_storage_roots=False,
                with_uncles=False):
        """
        serializes the block
        with_state:             include state for all accounts
        full_transactions:      include serialized tx (hashes otherwise)
        with_uncles:            include uncle hashes
        """
        b = {}
        for name, typ, default in block_structure:
            b[name] = utils.printers[typ](getattr(self, name))
        txlist = []
        for i in range(self.transaction_count):
            tx_rlp = self.transactions.get(rlp.encode(utils.encode_int(i)))
            tx = rlp.decode(tx_rlp)
            receipt_rlp = self.receipts.get(rlp.encode(utils.encode_int(i)))
            msr, gas, mybloom, mylogs = rlp.decode(receipt_rlp)
            if full_transactions:
                txjson = transactions.Transaction.create(tx).to_dict()
            else:
                # tx hash
                txjson = utils.sha3(rlp.descend(tx_rlp, 0)).encode('hex')
            txlist.append({
                "tx": txjson,
                "medstate": msr.encode('hex'),
                "gas": str(utils.decode_int(gas)),
                "logs": mylogs,
                "bloom": mybloom.encode('hex')
            })
        b["transactions"] = txlist
        if with_state:
            state_dump = {}
            for address, v in self.state.to_dict().iteritems():
                state_dump[address.encode('hex')] = \
                    self.account_to_dict(address, with_storage_roots)
            b['state'] = state_dump
        if with_uncles:
            b['uncles'] = [
                utils.sha3(rlp.encode(u)).encode('hex') for u in self.uncles
            ]

        return b
Beispiel #37
0
 def verify_dc_sig(self, sig, msghash, msgsize, from_addr, data):
     # data comes in as array of byte array (bytes as ints, from js)
     tohash = byte_arrays_to_string(data)
     assert (msghash == utils.sha3(tohash))
     X, Y = ecdsa_raw_recover(msghash, sig)
     pX = utils.int_to_big_endian(X).encode('hex')
     pY = utils.int_to_big_endian(Y).encode('hex')
     pub = '04' + pX + pY
     return ecdsa_raw_verify(msghash, sig, pub.decode('hex'))
Beispiel #38
0
    def send(self, sender, host_port, data):
        log.debug('in send unreliable', counter=self.network.counter,
                  drop_this_one=not(self.network.counter % self.droprate))

        if self.network.counter % self.droprate:
            self.network.send(sender, host_port, data)
        else:
            self.network.track_send(sender, host_port, data)
            log.debug('dropped', data=format(pex(sha3(data))))
 def verify_dc_sig(self, sig, msghash, msgsize, from_addr, data):
     # data comes in as array of byte array (bytes as ints, from js)
     tohash = byte_arrays_to_string(data)
     assert (msghash == utils.sha3(tohash))
     X, Y = ecdsa_raw_recover(msghash, sig)
     pX = utils.int_to_big_endian(X).encode('hex')
     pY = utils.int_to_big_endian(Y).encode('hex')
     pub = '04'+pX+pY
     return ecdsa_raw_verify(msghash, sig, pub.decode('hex'))
Beispiel #40
0
 def send(self, sender, host_port, message):
     for cb in self.on_send_cbs:
         cb(sender, host_port, message)
     print 'in send unreliable', self.counter, self.counter % self.droprate
     self.counter += 1
     if (self.counter - 1) % self.droprate:
         self.protocols[host_port].receive(message)
     else:
         print('dropped message {}'.format(pex(sha3(message))))
Beispiel #41
0
 def parse(cls, data):
     if re.match('^[0-9a-fA-F]*$', data):
         data = data.decode('hex')
     o = rlp.decode(data)
     tx = cls(decode_int(o[0]),
              decode_int(o[1]),
              decode_int(o[2]),
              decode_int(o[3]),
              o[4].encode('hex'),
              o[5],
              decode_int(o[6]),
              decode_int(o[7]),
              decode_int(o[8]))
     rawhash = sha3(rlp.encode(tx.serialize(False)))
     pub = encode_pubkey(
         ecdsa_raw_recover(rawhash, (tx.v, tx.r, tx.s)), 'bin')
     tx.sender = sha3(pub[1:])[-20:].encode('hex')
     return tx
Beispiel #42
0
 def quickcontract(self, gasprice, startgas, value, code, pkey_hex):
     sender = privtoaddr(pkey_hex)
     nonce = self.getnonce(sender)
     tx = contract(nonce, gasprice, startgas, value, code)
     formatted_rlp = [sender.decode('hex'), utils.int_to_big_endian(nonce)]
     addr = utils.sha3(rlp.encode(formatted_rlp))[12:].encode('hex')
     o = self.applytx(sign(tx, pkey_hex))
     o['addr'] = addr
     return o
Beispiel #43
0
 def quickcontract(self, gasprice, startgas, value, code, pkey_hex):
     sender = privtoaddr(pkey_hex)
     nonce = self.getnonce(sender)
     tx = contract(nonce, gasprice, startgas, value, code)
     formatted_rlp = [sender.decode('hex'), utils.int_to_big_endian(nonce)]
     addr = utils.sha3(rlp.encode(formatted_rlp))[12:].encode('hex')
     o = self.applytx(sign(tx, pkey_hex))
     o['addr'] = addr
     return o
Beispiel #44
0
    def send(self, sender, host_port, data):
        log.debug('in send unreliable', counter=self.network.counter,
                  drop_this_one=not(self.network.counter % self.droprate))

        if self.network.counter % self.droprate:
            self.network.send(sender, host_port, data)
        else:
            self.network.track_send(sender, host_port, data)
            log.debug('dropped', data=format(pex(sha3(data))))
Beispiel #45
0
    def __init__(self, data=None):

        self.reward = 10 ** 18
        self.gas_consumed = 0
        self.gaslimit = 1000000  # for now

        if not data:
            self.number = 0
            self.prevhash = ''
            self.uncles_root = ''
            self.coinbase = '0' * 40
            self.state = Trie(get_db_path())
            self.transactions_root = ''
            self.transactions = []
            self.uncles = []
            self.difficulty = 2 ** 23
            self.timestamp = 0
            self.extradata = ''
            self.nonce = 0
            return

        if re.match('^[0-9a-fA-F]*$', data):
            data = data.decode('hex')

        header,  transaction_list, self.uncles = rlp.decode(data)
        self.number = decode_int(header[0])
        self.prevhash = header[1]
        self.uncles_root = header[2]
        self.coinbase = header[3].encode('hex')
        self.state = Trie(STATEDB_DIR, header[4])
        self.transactions_root = header[5]
        self.difficulty = decode_int(header[6])
        self.timestamp = decode_int(header[7])
        self.extradata = header[8]
        self.nonce = decode_int(header[9])
        self.transactions = [Transaction(x) for x in transaction_list]

        # Verifications
        if self.state.root != '' and self.state.db.get(self.state.root) == '':
            raise Exception("State Merkle root not found in database!")
        if sha3(rlp.encode(transaction_list)) != self.transactions_root:
            raise Exception("Transaction list root hash does not match!")
        if sha3(rlp.encode(self.uncles)) != self.uncles_root:
            raise Exception("Uncle root hash does not match!")
Beispiel #46
0
    def __init__(self, data=None):

        self.reward = 10**18
        self.gas_consumed = 0
        self.gaslimit = 1000000  # for now

        if not data:
            self.number = 0
            self.prevhash = ''
            self.uncles_root = ''
            self.coinbase = '0' * 40
            self.state = Trie('statedb')
            self.transactions_root = ''
            self.transactions = []
            self.uncles = []
            self.difficulty = 2**23
            self.timestamp = 0
            self.extradata = ''
            self.nonce = 0
            return

        if re.match('^[0-9a-fA-F]*$', data):
            data = data.decode('hex')

        header, transaction_list, self.uncles = rlp.decode(data)
        self.number = decode_int(header[0])
        self.prevhash = header[1]
        self.uncles_root = header[2]
        self.coinbase = header[3].encode('hex')
        self.state = Trie('statedb', header[4])
        self.transactions_root = header[5]
        self.difficulty = decode_int(header[6])
        self.timestamp = decode_int(header[7])
        self.extradata = header[8]
        self.nonce = decode_int(header[9])
        self.transactions = [Transaction(x) for x in transaction_list]

        # Verifications
        if self.state.root != '' and self.state.db.get(self.state.root) == '':
            raise Exception("State Merkle root not found in database!")
        if sha3(rlp.encode(transaction_list)) != self.transactions_root:
            raise Exception("Transaction list root hash does not match!")
        if sha3(rlp.encode(self.uncles)) != self.uncles_root:
            raise Exception("Uncle root hash does not match!")
Beispiel #47
0
    def deserialize_child(self, rlpdata):
        """
        deserialization w/ replaying transactions
        """
        header_args, transaction_list, uncles = rlp.decode(rlpdata)
        assert len(header_args) == len(block_structure)
        kargs = dict(transaction_list=transaction_list, uncles=uncles)
        # Deserialize all properties
        for i, (name, typ, default) in enumerate(block_structure):
            kargs[name] = utils.decoders[typ](header_args[i])

        block = Block.init_from_parent(self, kargs['coinbase'],
                                       extra_data=kargs['extra_data'],
                                       timestamp=kargs['timestamp'],
                                       uncles=uncles)

        # replay transactions
        for tx_lst_serialized, _state_root, _gas_used_encoded in \
                transaction_list:
            tx = transactions.Transaction.create(tx_lst_serialized)
#            logger.debug('state:\n%s', utils.dump_state(block.state))
#            logger.debug('applying %r', tx)
            success, output = processblock.apply_transaction(block, tx)
            #block.add_transaction_to_list(tx) # < this is done by processblock
#            logger.debug('state:\n%s', utils.dump_state(block.state))
            logger.debug('d %s %s', _gas_used_encoded, block.gas_used)
            assert utils.decode_int(_gas_used_encoded) == block.gas_used, \
                "Gas mismatch (ours %d, theirs %d) on block: %r" % \
                (block.gas_used, _gas_used_encoded, block.to_dict(False, True, True))
            assert _state_root == block.state.root_hash, \
                "State root mismatch (ours %r theirs %r) on block: %r" % \
                (block.state.root_hash.encode('hex'),
                 _state_root.encode('hex'),
                 block.to_dict(False, True, True))

        block.finalize()

        block.uncles_hash = kargs['uncles_hash']
        block.nonce = kargs['nonce']
        block.min_gas_price = kargs['min_gas_price']

        # checks
        assert block.prevhash == self.hash

        assert block.gas_used == kargs['gas_used']
        assert block.gas_limit == kargs['gas_limit']
        assert block.timestamp == kargs['timestamp']
        assert block.difficulty == kargs['difficulty']
        assert block.number == kargs['number']
        assert block.extra_data == kargs['extra_data']
        assert utils.sha3(rlp.encode(block.uncles)) == kargs['uncles_hash']

        assert block.tx_list_root == kargs['tx_list_root']
        assert block.state.root_hash == kargs['state_root'], (block.state.root_hash, kargs['state_root'])

        return block
Beispiel #48
0
 def _add_transactions(self, blk):
     "'tx_hash' -> 'rlp([blockhash,tx_number])"
     for i in range(blk.transaction_count):
         i_enc = utils.encode_int(i)
         # work on rlp data to avoid unnecessary de/serialization
         td = blk.transactions.get(rlp.encode(i_enc))
         tx = rlp.descend(td, 0)
         key = utils.sha3(tx)
         value = rlp.encode([blk.hash, i_enc])
         self.db.put(key, value)
Beispiel #49
0
 def _add_transactions(self, blk):
     "'tx_hash' -> 'rlp([blockhash,tx_number])"
     for i in range(blk.transaction_count):
         i_enc = utils.encode_int(i)
         # work on rlp data to avoid unnecessary de/serialization
         td = blk.transactions.get(rlp.encode(i_enc))
         tx = rlp.descend(td, 0)
         key = utils.sha3(tx)
         value = rlp.encode([blk.hash, i_enc])
         self.db.put(key, value)
Beispiel #50
0
 def root_with(self, lock=None, exclude=None):
     assert not lock or isinstance(lock, Lock)
     assert not exclude or isinstance(exclude, Lock)
     lock_hash = exclude_hash = None
     # temporarily add / remove
     if lock:
         lock_hash = sha3(lock.asstring)
         self._cached_lock_hashes.append(lock_hash)
     if exclude:
         exclude_hash = sha3(exclude.asstring)
         self._cached_lock_hashes.remove(exclude_hash)
     # calc
     r = merkleroot(self._cached_lock_hashes)
     # restore
     if lock_hash:
         assert lock_hash in self._cached_lock_hashes
         self._cached_lock_hashes.remove(lock_hash)
     if exclude:
         self._cached_lock_hashes.append(exclude_hash)
     return r
    def __init__(self, nonce, gasprice, startgas, to, value, data, v=0, r=0,
                 s=0):
        self.nonce = nonce
        self.gasprice = gasprice
        self.startgas = startgas
        self.to = to
        self.value = value
        self.data = data
        self.v, self.r, self.s = v, r, s

        # Determine sender
        if self.r and self.s:
            rawhash = utils.sha3(self.serialize(False))
            pub = encode_pubkey(
                ecdsa_raw_recover(rawhash, (self.v, self.r, self.s)),
                'bin')
            self.sender = utils.sha3(pub[1:])[-20:].encode('hex')
        # does not include signature
        else:
            self.sender = 0
Beispiel #52
0
    def _encode_node(self, node):
        if node == BLANK_NODE:
            return BLANK_NODE
        assert isinstance(node, list)
        rlpnode = rlp.encode(node)
        if len(rlpnode) < 32:
            return node

        hashkey = utils.sha3(rlpnode)
        self.db.put(hashkey, rlpnode)
        return hashkey
Beispiel #53
0
    def _encode_node(self, node, put_in_db=True):
        if node == BLANK_NODE:
            return BLANK_NODE
        rlpnode = encode_optimized(node)
        if len(rlpnode) < 32:
            return node
        hashkey = utils.sha3(rlpnode)
        if put_in_db:
            self.db.put(hashkey, str_to_bytes(rlpnode))

        return hashkey
Beispiel #54
0
 def hash_message(self, msg):
     prefix = b''
     if self.category == 0:
         prefix = b'Allocate:\n'
     elif self.category == 1:
         prefix = b'Delegate:\n'
     elif self.category == 2:
         prefix = b'MapServer:\n'
     elif self.category == 3:
         prefix = b'Locator:\n'
     return sha3(
         int_to_bytes(len(prefix)) + prefix + int_to_bytes(len(msg)) + msg)
Beispiel #55
0
    def __init__(self, nonce, gasprice, startgas, to, value, data, v=0, r=0,
                 s=0):
        self.nonce = nonce
        self.gasprice = gasprice
        self.startgas = startgas
        self.to = to
        self.value = value
        self.data = data
        self.v, self.r, self.s = v, r, s
        self.logs = []

        # Determine sender
        if self.r < N and self.s < P and self.v >= 27 and self.v <= 28:
            rawhash = utils.sha3(self.serialize(False))
            pub = encode_pubkey(
                ecdsa_raw_recover(rawhash, (self.v, self.r, self.s)),
                'bin')
            self.sender = utils.sha3(pub[1:])[-20:].encode('hex')
        # does not include signature
        else:
            self.sender = 0
Beispiel #56
0
    def close(self, sender, last_sent_transfers, *unlocked):
        """"
        can be called multiple times. lock period starts with first valid call.

        todo:
            if challenged, keep track of who provided the last valid answer, punish the wrongdoer
                here, check that participants only updates their own balance are counted,
                    because they could sign something for the other party to blame it.

        last_sent_transfers: [rlp(transfer), ] max 2
        unlocked: [(merkle_proof, locked_rlp, secret)), ...]

        """
        assert sender in self.participants
        assert 0 <= len(last_sent_transfers) <= 2

        # register / update claims
        for t in last_sent_transfers:  # fixme rlp encoded
            # check transfer signature
            assert t.sender in self.participants

            # update valid claims
            if not self.participants[t.sender]['last_sent_transfer'] or \
                    self.participants[t.sender]['last_sent_transfer'].nonce < t.nonce:
                self.participants[t.sender]['last_sent_transfer'] = t

        # register un-locked
        last_sent = self.participants[self.partner(
            sender)]['last_sent_transfer']
        for merkle_proof, locked_rlp, secret in unlocked:
            locked = rlp.decode(locked_rlp, messages.Lock)
            assert locked.hashlock == sha3(secret)
            assert check_proof(merkle_proof, last_sent.locksroot,
                               sha3(locked_rlp))
            self.participants[self.partner(
                t.sender)]['unlocked'].append(locked)

        # mark closed
        if not self.closed:
            self.closed = self.chain.block_number
Beispiel #57
0
def create_network(num_nodes=8,
                   num_assets=1,
                   channels_per_node=3,
                   transport_class=DummyTransport):
    import random
    random.seed(42)

    # globals
    discovery = Discovery()
    chain = BlockChain()

    # create apps
    apps = [
        mk_app(i, chain, discovery, transport_class) for i in range(num_nodes)
    ]

    # create assets
    for i in range(num_assets):
        chain.add_asset(asset_address=sha3('asset:%d' % i)[:20])
    assert len(chain.asset_addresses) == num_assets

    # create channel contracts
    for asset_address in chain.asset_addresses:
        channelmanager = chain.channelmanager_by_asset(asset_address)
        assert isinstance(channelmanager, ChannelManagerContract)
        assert channels_per_node < len(apps)
        for app in apps:
            capps = list(apps)  # copy
            capps.remove(app)
            netting_contracts = channelmanager.nettingcontracts_by_address(
                app.raiden.address)
            while len(netting_contracts) < channels_per_node and capps:
                a = random.choice(capps)
                assert a != app
                capps.remove(a)
                a_nettting_contracts = channelmanager.nettingcontracts_by_address(
                    a.raiden.address)
                if not set(netting_contracts).intersection(set(a_nettting_contracts)) \
                        and len(a_nettting_contracts) < channels_per_node:
                    # print pex(a.raiden.address), pex(app.raiden.address)
                    c = channelmanager.new(a.raiden.address,
                                           app.raiden.address)
                    netting_contracts.append(c)

                    # add deposit of asset
                    for address in (app.raiden.address, a.raiden.address):
                        c.deposit(address, amount=2**240)

    for app in apps:
        app.raiden.setup_assets()

    return apps
Beispiel #58
0
def sha3(string):
    """Calculate the SHA3-256 hash of some input.

    This command calculates the 256-bit SHA3 hash of STRING and prints the
    result in hex-encoding. STRING is interpreted as a latin-1 encoded byte
    array.
    """
    try:
        byte_array = string.encode('latin1')
    except UnicodeEncodeError:
        raise click.BadParameter('STRING must be encoded in latin-1')
    else:
        click.echo(utils.sha3(byte_array).encode('hex'))
Beispiel #59
0
 def validate_uncles(self):
     if utils.sha3(rlp.encode(self.uncles)) != self.uncles_hash:
         sys.stderr.write(
             utils.sha3(rlp.encode(self.uncles)).encode('hex') + '   ' +
             self.uncles_hash.encode('hex') + '\n\n\n')
         return False
     # Check uncle validity
     ancestor_chain = [self]
     # Uncle can have a block from 2-7 blocks ago as its parent
     for i in [1, 2, 3, 4, 5, 6, 7]:
         if ancestor_chain[-1].number > 0:
             ancestor_chain.append(ancestor_chain[-1].get_parent())
     ineligible = []
     # Uncles of this block cannot be direct ancestors and cannot also
     # be uncles included 1-6 blocks ago
     for ancestor in ancestor_chain[1:]:
         ineligible.extend(ancestor.uncles)
     ineligible.extend([b.list_header() for b in ancestor_chain])
     eligible_ancestor_hashes = [x.hash for x in ancestor_chain[2:]]
     for uncle in self.uncles:
         if not check_header_pow(uncle):
             sys.stderr.write('1\n\n')
             return False
         # uncle's parent cannot be the block's own parent
         prevhash = uncle[block_structure_rev['prevhash'][0]]
         if prevhash not in eligible_ancestor_hashes:
             logger.debug("%r: Uncle does not have a valid ancestor", self)
             sys.stderr.write('2 ' + prevhash.encode('hex') + ' ' + str(
                 map(lambda x: x.encode('hex'), eligible_ancestor_hashes)) +
                              '\n\n')
             return False
         if uncle in ineligible:
             sys.stderr.write('3\n\n')
             logger.debug("%r: Duplicate uncle %r", self,
                          utils.sha3(rlp.encode(uncle)).encode('hex'))
             return False
         ineligible.append(uncle)
     return True