def get_transaction(self, txhash): "return (tx, block, index)" blockhash, tx_num_enc = rlp.decode(self.db.get(txhash)) blk = rlp.decode(self.db.get(blockhash), blocks.Block, db=self.db) num = utils.decode_int(tx_num_enc) tx_data = blk.get_transaction(num) return tx_data, blk, num
def cleanup(self, epoch): try: death_row_node = self.db.get('deathrow:'+str(epoch)) except: death_row_node = rlp.encode([]) death_row_nodes = rlp.decode(death_row_node) pruned = 0 for nodekey in death_row_nodes: try: refcount, val = rlp.decode(self.db.get(b'r:'+nodekey)) if utils.decode_int(refcount) == DEATH_ROW_OFFSET + epoch: self.db.delete(b'r:'+nodekey) pruned += 1 except: pass sys.stderr.write('%d nodes successfully pruned\n' % pruned) # Delete the deathrow after processing it try: self.db.delete('deathrow:'+str(epoch)) except: pass # Delete journals that are too old try: self.db.delete('journal:'+str(epoch - self.ttl)) except: pass
def get_transaction(self, txhash): "return (tx, block, index)" blockhash, tx_num_enc = rlp.decode(self.db.get(txhash)) blk = rlp.decode(self.db.get(blockhash), blocks.Block, env=self.env) num = utils.decode_int(tx_num_enc) tx_data = blk.get_transaction(num) return tx_data, blk, num
def get_refcount(self, k): try: o = utils.decode_int(self.db.get(b'r:'+k))[0] if o >= DEATH_ROW_OFFSET: return 0 return o except: return 0
def tot_rlp_cost(self, nonce, address): cost = RLP_BASE + rlp_cost(nonce) cost += input_data_cost(nonce) if isinstance(address, str): cost += input_data_cost(utils.decode_int( utils.decode_hex(address)), num_bytes=20) else: cost += input_data_cost(address, num_bytes=20) return cost
def dec_refcount(self, k): # raise Exception("WHY AM I CHANGING A REFCOUNT?!:?") node_object = rlp.decode(self.db.get(b'r:'+k)) refcount = utils.decode_int(node_object[0]) if self.logging: sys.stderr.write('decreasing %s to: %d\n' % (utils.encode_hex(k), refcount - 1)) assert refcount > 0 self.journal.append([node_object[0], k]) new_refcount = utils.encode_int(refcount - 1) self.db.put(b'r:'+k, rlp.encode([new_refcount, node_object[1]])) if new_refcount == ZERO_ENCODED: self.death_row.append(k)
def verify_independent_transaction_spv_proof(db, proof): _, prevheader, header, index, nodes = rlp.decode(proof) index = utils.decode_int(index) pb = blocks.Block.deserialize_header(prevheader) b = blocks.Block.init_from_header(db, header) b.set_proof_mode(blocks.VERIFYING, nodes) if index != 0: pre_med, pre_gas, _, _ = b.get_receipt(index - 1) else: pre_med, pre_gas = pb['state_root'], '' if utils.sha3(rlp.encode(prevheader)) != b.prevhash: return False b.state_root = pre_med b.gas_used = utils.decode_int(pre_gas) tx = b.get_transaction(index) post_med, post_gas, bloom, logs = b.get_receipt(index) tx = transactions.Transaction.create(tx) o = verify_transaction_spv_proof(b, tx, nodes) if b.state_root == post_med: if b.gas_used == utils.decode_int(post_gas): if [x.serialize() for x in b.logs] == logs: if b.mk_log_bloom() == bloom: return o return False
def make_match(self, buyer, seller): if buyer.epoch < self.current_block + self.SEALED_WINDOW: print(self.name, 'making sealed offer', buyer.id, seller.id) # TODO: check hash for adding sealed offer, ie hash preferences? # TODO: rework this, see reveal hash_arr = [buyer.epoch, buyer.id, seller.id] shasum = utils.sha3(''.join(map(lambda x: utils.zpad(utils.encode_int(x), 32), hash_arr))) # shasum = utils.sha3(hash_arr) # TODO check epoch against SEALED_WINDOW offer_id = self.market.add_sealed_offer(buyer.id, shasum) print(self.name, 'shasum', utils.decode_int(shasum)) # TODO, combine preferences # TODO rework this, can probably just have buyer and seller instead of id's only offer = Offer(offer_id, buyer.epoch, buyer.id, seller.id, shasum, buyer.preferences) self.sealed_offers.append(offer)
def inc_refcount(self, k, v): # raise Exception("WHY AM I CHANGING A REFCOUNT?!:?") try: node_object = rlp.decode(self.db.get(b'r:'+k)) refcount = utils.decode_int(node_object[0]) self.journal.append([node_object[0], k]) if refcount >= DEATH_ROW_OFFSET: refcount = 0 new_refcount = utils.encode_int(refcount + 1) self.db.put(b'r:'+k, rlp.encode([new_refcount, v])) if self.logging: sys.stderr.write('increasing %s %r to: %d\n' % (utils.encode_hex(k), v, refcount + 1)) except: self.db.put(b'r:'+k, rlp.encode([ONE_ENCODED, v])) self.journal.append([ZERO_ENCODED, k]) if self.logging: sys.stderr.write('increasing %s %r to: %d\n' % (utils.encode_hex(k), v, 1))
def make_match(self, buyer, seller): if buyer.epoch < self.current_block + self.SEALED_WINDOW: print(self.name, 'making sealed offer', buyer.id, seller.id) # TODO: check hash for adding sealed offer, ie hash preferences? # TODO: rework this, see reveal hash_arr = [buyer.epoch, buyer.id, seller.id] shasum = utils.sha3(''.join( map(lambda x: utils.zpad(utils.encode_int(x), 32), hash_arr))) # shasum = utils.sha3(hash_arr) # TODO check epoch against SEALED_WINDOW offer_id = self.market.add_sealed_offer(buyer.id, shasum) print(self.name, 'shasum', utils.decode_int(shasum)) # TODO, combine preferences # TODO rework this, can probably just have buyer and seller instead of id's only offer = Offer(offer_id, buyer.epoch, buyer.id, seller.id, shasum, buyer.preferences) self.sealed_offers.append(offer)
def chain_difficulty(self): """Get the summarized difficulty. If the summarized difficulty is not stored in the database, it will be calculated recursively and put in the database. """ if self.is_genesis(): return self.difficulty elif b'difficulty:' + encode_hex(self.hash) in self.db: encoded = self.db.get(b'difficulty:' + encode_hex(self.hash)) return utils.decode_int(encoded) else: o = self.difficulty + self.get_parent().chain_difficulty() # o += sum([uncle.difficulty for uncle in self.uncles]) self.state.db.put(b'difficulty:' + encode_hex(self.hash), utils.encode_int(o)) return o return rlp.decode(rlp.encode(l)) == l
def decode_int_from_hex(x): r = utils.decode_int(decode_hex(x).lstrip(b"\x00")) return r
def test(): s = t.state() test_company = s.abi_contract('company.se', ADMIN_ACCOUNT=utils.decode_int(t.a0)) order_book = s.abi_contract('orders.se') test_currency = s.abi_contract('currency.se', sender=t.k0) assert test_company.getAdmin() == t.a0.encode('hex') # Issue 1000 shares to user a1 test_company.issueShares(1000, t.a1, sender=t.k0) # Issue 50000 coins to users a2 and a3 test_currency.sendCoin(50000, t.a2, sender=t.k0) test_currency.sendCoin(50000, t.a3, sender=t.k0) # User a1 can have as many shares as he wants, but must retain at # least 800 test_company.setShareholderMaxShares(t.a1, 2**100, sender=t.k0) test_company.setShareholderMinShares(t.a1, 800, sender=t.k0) # User a2 can have up to 500 shares test_company.setShareholderMaxShares(t.a2, 500, sender=t.k0) # User a2 tries to give himself the right to unlimited shares, # fails because he is not the admin test_company.setShareholderMaxShares(t.a2, 2**100, sender=t.k2) # A few sanity checks assert test_company.getCurrentShareholdingsOf(t.a1) == 1000 assert test_company.getShareholderMinShares(t.a1) == 800 assert test_company.getShareholderMaxShares(t.a2) == 500 # User a1 transfers 150 shares to a2 assert test_company.sendCoin(150, t.a2, sender=t.k1) is True # User a1 tries to transfer 150 shares to a2 again, fails because # such a transaction would result a1 having 700 shares, which is # below his limit assert test_company.sendCoin(150, t.a2, sender=t.k1) is False # Check shareholdings assert test_company.getCurrentShareholdingsOf(t.a1) == 850 assert test_company.getCurrentShareholdingsOf(t.a2) == 150 # Authorize the order book contract to accept lockups test_company.setContractAuthorized(order_book.address, True) # User a1 puts up 50 shares for sale; however, he tries to do # this without first authorizing the order book to withdraw so # the operation fails assert order_book.mkSellOrder(test_company.address, 50, test_currency.address, 10000, sender=t.k1) == -1 # Now, try to create the order properly test_company.authorizeLockup(order_book.address, 50, sender=t.k1) _id = order_book.mkSellOrder(test_company.address, 50, test_currency.address, 10000, sender=t.k1) assert _id >= 0 assert test_company.getLockedShareholdingsOf(t.a1) == 50 # Accept the order by a3. This should fail because a3 has not # authorized the order_book to withdraw coins assert order_book.claimSellOrder(_id, sender=t.k3) is False # Do the authorization test_currency.approveOnce(order_book.address, 10000, sender=t.k3) # It should still fail because a3 is not authorized to hold shares assert order_book.claimSellOrder(_id, sender=t.k3) is False # Now do it properly test_currency.approveOnce(order_book.address, 10000, sender=t.k2) assert order_book.claimSellOrder(_id, sender=t.k2) is True # Check shareholdings and balances assert test_company.getCurrentShareholdingsOf(t.a1) == 800 assert test_company.getCurrentShareholdingsOf(t.a2) == 200 assert test_company.getLockedShareholdingsOf(t.a1) == 0 assert test_currency.coinBalanceOf(t.a1) == 10000 assert test_currency.coinBalanceOf(t.a2) == 40000 assert test_currency.coinBalanceOf(t.a3) == 50000 # Authorize a3 to hold shares test_company.setShareholderMaxShares(t.a3, 500) # A3 buys shares test_currency.approveOnce(order_book.address, 20000, sender=t.k3) _id2 = order_book.mkBuyOrder(test_company.address, 100, test_currency.address, 20000, sender=t.k3) assert _id2 >= 0, _id2 test_company.authorizeLockup(order_book.address, 100, sender=t.k2) assert order_book.claimBuyOrder(_id2, sender=t.k2) is True # Check shareholdings and balances assert test_company.getCurrentShareholdingsOf(t.a1) == 800 assert test_company.getCurrentShareholdingsOf(t.a2) == 100 assert test_company.getCurrentShareholdingsOf(t.a3) == 100 assert test_company.getLockedShareholdingsOf(t.a1) == 0 assert test_currency.coinBalanceOf(t.a1) == 10000 assert test_currency.coinBalanceOf(t.a2) == 60000 assert test_currency.coinBalanceOf(t.a3) == 30000
def test(): s = t.state() test_company = s.abi_contract("company.se", ADMIN_ACCOUNT=utils.decode_int(t.a0)) order_book = s.abi_contract("orders.se") test_currency = s.abi_contract("currency.se", sender=t.k0) assert test_company.getAdmin() == t.a0.encode("hex") # Issue 1000 shares to user a1 test_company.issueShares(1000, t.a1, sender=t.k0) # Issue 50000 coins to users a2 and a3 test_currency.sendCoin(50000, t.a2, sender=t.k0) test_currency.sendCoin(50000, t.a3, sender=t.k0) # User a1 can have as many shares as he wants, but must retain at # least 800 test_company.setShareholderMaxShares(t.a1, 2 ** 100, sender=t.k0) test_company.setShareholderMinShares(t.a1, 800, sender=t.k0) # User a2 can have up to 500 shares test_company.setShareholderMaxShares(t.a2, 500, sender=t.k0) # User a2 tries to give himself the right to unlimited shares, # fails because he is not the admin test_company.setShareholderMaxShares(t.a2, 2 ** 100, sender=t.k2) # A few sanity checks assert test_company.getCurrentShareholdingsOf(t.a1) == 1000 assert test_company.getShareholderMinShares(t.a1) == 800 assert test_company.getShareholderMaxShares(t.a2) == 500 # User a1 transfers 150 shares to a2 assert test_company.sendCoin(150, t.a2, sender=t.k1) is True # User a1 tries to transfer 150 shares to a2 again, fails because # such a transaction would result a1 having 700 shares, which is # below his limit assert test_company.sendCoin(150, t.a2, sender=t.k1) is False # Check shareholdings assert test_company.getCurrentShareholdingsOf(t.a1) == 850 assert test_company.getCurrentShareholdingsOf(t.a2) == 150 # Authorize the order book contract to accept lockups test_company.setContractAuthorized(order_book.address, True) # User a1 puts up 50 shares for sale; however, he tries to do # this without first authorizing the order book to withdraw so # the operation fails assert order_book.mkSellOrder(test_company.address, 50, test_currency.address, 10000, sender=t.k1) == -1 # Now, try to create the order properly test_company.authorizeLockup(order_book.address, 50, sender=t.k1) _id = order_book.mkSellOrder(test_company.address, 50, test_currency.address, 10000, sender=t.k1) assert _id >= 0 assert test_company.getLockedShareholdingsOf(t.a1) == 50 # Accept the order by a3. This should fail because a3 has not # authorized the order_book to withdraw coins assert order_book.claimSellOrder(_id, sender=t.k3) is False # Do the authorization test_currency.approveOnce(order_book.address, 10000, sender=t.k3) # It should still fail because a3 is not authorized to hold shares assert order_book.claimSellOrder(_id, sender=t.k3) is False # Now do it properly test_currency.approveOnce(order_book.address, 10000, sender=t.k2) assert order_book.claimSellOrder(_id, sender=t.k2) is True # Check shareholdings and balances assert test_company.getCurrentShareholdingsOf(t.a1) == 800 assert test_company.getCurrentShareholdingsOf(t.a2) == 200 assert test_company.getLockedShareholdingsOf(t.a1) == 0 assert test_currency.coinBalanceOf(t.a1) == 10000 assert test_currency.coinBalanceOf(t.a2) == 40000 assert test_currency.coinBalanceOf(t.a3) == 50000 # Authorize a3 to hold shares test_company.setShareholderMaxShares(t.a3, 500) # A3 buys shares test_currency.approveOnce(order_book.address, 20000, sender=t.k3) _id2 = order_book.mkBuyOrder(test_company.address, 100, test_currency.address, 20000, sender=t.k3) assert _id2 >= 0, _id2 test_company.authorizeLockup(order_book.address, 100, sender=t.k2) assert order_book.claimBuyOrder(_id2, sender=t.k2) is True # Check shareholdings and balances assert test_company.getCurrentShareholdingsOf(t.a1) == 800 assert test_company.getCurrentShareholdingsOf(t.a2) == 100 assert test_company.getCurrentShareholdingsOf(t.a3) == 100 assert test_company.getLockedShareholdingsOf(t.a1) == 0 assert test_currency.coinBalanceOf(t.a1) == 10000 assert test_currency.coinBalanceOf(t.a2) == 60000 assert test_currency.coinBalanceOf(t.a3) == 30000