def signing_hash(self): return sha3( 'prepare%s%s%s' % ( encode_int32(self.epoch), self.hash, encode_int32(self.epoch_source) ) )
def withdraw(self, gasprice=20 * 10**9): h = sha3(b'withdrawwithdrawwithdrawwithdraw') v, r, s = ecsign(h, self.key) sigdata = encode_int32(v) + encode_int32(r) + encode_int32(s) txdata = casper_ct.encode('startWithdrawal', [self.indices[0], self.indices[1], sigdata]) tx = Transaction(self.chain.state.get_nonce(self.address), gasprice, 650000, self.chain.config['CASPER_ADDR'], 0, txdata).sign(self.key) self.chain.add_transaction(tx) self.network.broadcast(self, tx) print 'Withdrawing!'
def signing_hash(self): return sha3( 'commit%s%s' % ( encode_int32(self.epoch), self.hash ) )
def proc_ecmul(ext, msg): if not ext.post_metropolis_hardfork(): return 1, msg.gas, [] import py_ecc.optimized_bn128 as bn128 FQ = bn128.FQ print('ecmul proc', msg.gas) if msg.gas < opcodes.GECMUL: return 0, 0, [] x = msg.data.extract32(0) y = msg.data.extract32(32) m = msg.data.extract32(64) p = validate_point(x, y) if p is False: return 0, 0, [] o = bn128.normalize(bn128.multiply(p, m)) return (1, msg.gas - opcodes.GECMUL, [ safe_ord(c) for c in (encode_int32(o[0].n) + encode_int32(o[1].n)) ])
def get_storage_data(self, key): ''' get storage data ''' if key not in self.storage_cache: v = self.storage_trie.get(utils.encode_int32(key)) self.storage_cache[key] = utils.big_endian_to_int( rlp.decode(v) if v else b'') return self.storage_cache[key]
def verify1ZKP(self, proof, gen1, gen2, verbal): #print proof v, sh, e, z = proof if verbal: print "Verifying ZKP..." if verbal: print "e = " + str(e) + "\nIntermediates" a1 = ec.add(ec.multiply(gen1, z), ec.multiply(sh, e)) a2 = ec.add(ec.multiply(gen2, z), ec.multiply(v, e)) if verbal: print conc([str(ele) for ele in [a1[0], a1[1], a2[0], a2[1]]]) arr = [sh[0], sh[1], v[0], v[1], a1[0], a1[1], a2[0], a2[1]] toBeHashed = bytes('') for ele in arr: toBeHashed += encode_int32(ele) eVerify = sha3(toBeHashed) e = encode_int32(e) if verbal: print "Recovered e : " + mpz(codecs.encode(eVerify, 'hex'), 16).digits() return eVerify == e
def proc_ecadd(ext, msg): if not ext.post_metropolis_hardfork(): return 1, msg.gas, [] import py_ecc.optimized_bn128 as bn128 FQ = bn128.FQ print('ecadd proc:', msg.gas) if msg.gas < opcodes.GECADD: return 0, 0, [] x1 = msg.data.extract32(0) y1 = msg.data.extract32(32) x2 = msg.data.extract32(64) y2 = msg.data.extract32(96) p1 = validate_point(x1, y1) p2 = validate_point(x2, y2) if p1 is False or p2 is False: return 0, 0, [] o = bn128.normalize(bn128.add(p1, p2)) return 1, msg.gas - \ opcodes.GECADD, [safe_ord(x) for x in ( encode_int32(o[0].n) + encode_int32(o[1].n))]
def get_storage_data(self, key): """get storage data. :param key: :return: """ if key not in self.storage_cache: v = self.storage_trie.get(utils.encode_int32(key)) self.storage_cache[key] = utils.big_endian_to_int( rlp.decode(v) if v else b"") return self.storage_cache[key]
def generate_genesis(path=None, num_participants=1): privkeys = [ utils.sha3(utils.to_string(i)) for i in range(num_participants) ] addrs = [utils.privtoaddr(k) for k in privkeys] deposit_sizes = [i * 500 + 500 for i in range(num_participants)] randaos = [RandaoManager(utils.sha3(k)) for k in privkeys] validators = [(generate_validation_code(a), ds * 10**18, r.get(9999), a) for a, ds, r in zip(addrs, deposit_sizes, randaos)] s = make_casper_genesis(validators=validators, alloc={a: { 'balance': 10**18 } for a in addrs}, timestamp=int(time.time()), epoch_length=100) genesis_hash = apply_const_message( s, sender=casper_config['METROPOLIS_ENTRY_POINT'], to=casper_config['METROPOLIS_BLOCKHASH_STORE'], data=utils.encode_int32(0)) genesis_number = call_casper(s, 'getBlockNumber') print('genesis block hash: %s' % utils.encode_hex(genesis_hash)) print('genesis block number: %d' % genesis_number) print('%d validators: %r' % (num_participants, [utils.encode_hex(a) for a in addrs])) snapshot = s.to_snapshot() header = s.prev_headers[0] genesis = { "nonce": "0x" + utils.encode_hex(header.nonce), "difficulty": utils.int_to_hex(header.difficulty), "mixhash": "0x" + utils.encode_hex(header.mixhash), "coinbase": "0x" + utils.encode_hex(header.coinbase), "timestamp": utils.int_to_hex(header.timestamp), "parentHash": "0x" + utils.encode_hex(header.prevhash), "extraData": "0x" + utils.encode_hex(header.extra_data), "gasLimit": utils.int_to_hex(header.gas_limit), "alloc": snapshot["alloc"] } if path: with open(path, 'w') as f: json.dump(genesis, f, sort_keys=False, indent=4, separators=(',', ': ')) print('casper genesis generated') else: return genesis
def prestart(self): super(ParityServer, self).prestart() if self.settings['jsonrpc_port'] is None: self.settings['jsonrpc_port'] = get_unused_port() if self.version < (1, 7, 0) and self.settings[ 'no_dapps'] is False and self.settings['dapps_port'] is None: self.settings['dapps_port'] = get_unused_port() if self.settings['node_key'] is None: self.settings['node_key'] = "{:0>64}".format( binascii.b2a_hex(os.urandom(32)).decode('ascii')) pub_x, pub_y = privtopub(binascii.a2b_hex(self.settings['node_key'])) pub = encode_int32(pub_x) + encode_int32(pub_y) self.public_key = "{:0>128}".format( binascii.b2a_hex(pub).decode('ascii')) # write chain file write_chain_file(self.version, self.chainfile, self.faucet, self.difficulty)
def mk_ecpairing_data(pts): o = b'' for p, q in pts: np, nq = py_pairing.normalize(p), py_pairing.normalize(q) o += encode_int32(np[0].n) + encode_int32(np[1].n) + \ encode_int32(nq[0].coeffs[1]) + encode_int32(nq[0].coeffs[0]) + \ encode_int32(nq[1].coeffs[1]) + encode_int32(nq[1].coeffs[0]) return o
def verifyZKP(self, shares, vArr, e, zArr, verbal): if verbal: print "\nVerification..." self.verifyByCode(vArr, verbal) n = len(shares) if verbal: print "\ne = " + str(e) + "\nIntermediates" toBeHashed = bytes('') for i in range(n): sh = shares[i] v = vArr[i] (a1,a2) = (ec.add(ec.multiply(self.publicKeys[i],zArr[i]),ec.multiply(shares[i],e)),\ ec.add(ec.multiply(self.generatorSecondary,zArr[i]),ec.multiply(vArr[i],e))) if verbal: print conc([str(ele) for ele in [a1[0], a1[1], a2[0], a2[1]]]) arr = [sh[0], sh[1], v[0], v[1], a1[0], a1[1], a2[0], a2[1]] for ele in arr: toBeHashed += encode_int32(ele) eVerify = sha3(toBeHashed) e = encode_int32(e) if verbal: print "Recovered e : " + mpz(codecs.encode(eVerify, 'hex'), 16).digits() #if verbal : print codecs.encode(str(e),'hex') return eVerify == e
def test_call_add_header_get_shard_head(chain): def get_colhdr(shard_id, parent_collation_hash, collation_coinbase=t.a0): period_length = 5 expected_period_number = num_blocks // period_length b = chain.chain.get_block_by_number(expected_period_number * period_length - 1) period_start_prevhash = b.header.hash tx_list_root = b"tx_list " * 4 post_state_root = b"post_sta" * 4 receipt_root = b"receipt " * 4 sighash = utils.sha3( rlp.encode([ shard_id, expected_period_number, period_start_prevhash, parent_collation_hash, tx_list_root, collation_coinbase, post_state_root, receipt_root ]) ) sig = sign(sighash, t.k0) return rlp.encode([ shard_id, expected_period_number, period_start_prevhash, parent_collation_hash, tx_list_root, collation_coinbase, post_state_root, receipt_root, sig ]) # register t.k0 as the validators tx = create_contract_tx(chain.head_state, t.k0, mk_validation_code(t.a0)) k0_valcode_addr = chain.direct_tx(tx) chain.mine(1) tx = call_deposit(chain.head_state, t.k0, DEPOSIT_SIZE, k0_valcode_addr, t.a0) chain.direct_tx(tx) chain.mine(1) # create collation header shard0_genesis_colhdr_hash = utils.encode_int32(0) colhdr = get_colhdr(0, shard0_genesis_colhdr_hash) colhdr_hash = utils.sha3(colhdr) assert call_valmgr(chain.head_state, 'get_shard_head', [0]) == shard0_genesis_colhdr_hash # message call test assert call_valmgr(chain.head_state, 'add_header', [colhdr], sender_addr=t.a0) # transaction call test # `add_header` verifies whether the colhdr is signed by the current # selected validator, using `sample` tx = call_tx_add_header(chain.head_state, t.k0, 0, colhdr) chain.direct_tx(tx) chain.mine(1) assert colhdr_hash == call_valmgr(chain.head_state, 'get_shard_head', [0])
def generate1ZKP(self, ex, gen1, gen2): sh = ec.multiply(gen1, ex) v = ec.multiply(gen2, ex) w = self.sample(self.order) (a1, a2) = (ec.multiply(gen1, w), ec.multiply(gen2, w)) print 'As : ' print[a1[0], a1[1], a2[0], a2[1]] arr = [sh[0], sh[1], v[0], v[1], a1[0], a1[1], a2[0], a2[1]] toBeHashed = bytes('') for ele in arr: toBeHashed += encode_int32(ele) e = sha3(toBeHashed) e = mpz(codecs.encode(str(e), 'hex'), 16) z = long(gmpy2.f_mod(w - ex * e, self.order)) e = long(e) return [v, sh, e, z]
def vm_execute(ext, msg, code): # precompute trace flag # if we trace vm, we're in slow mode anyway trace_vm = log_vm_op.is_active('trace') compustate = Compustate(gas=msg.gas) stk = compustate.stack mem = compustate.memory if code in code_cache: processed_code = code_cache[code] else: processed_code = preprocess_code(code) code_cache[code] = processed_code # print(processed_code.keys(), code) codelen = len(code) s = time.time() steps = 0 _prevop = None # for trace only while compustate.pc in processed_code: ops, minstack, maxstack, totgas, nextpos = processed_code[ compustate.pc] if len(compustate.stack) < minstack: return vm_exception('INSUFFICIENT STACK') if len(compustate.stack) > maxstack: return vm_exception('STACK SIZE LIMIT EXCEEDED') if totgas > compustate.gas: return vm_exception('OUT OF GAS %d %d' % (totgas, compustate.gas)) jumped = False compustate.gas -= totgas compustate.pc = nextpos # Invalid operation; can only come at the end of a chunk if ops[-1][0] == 'INVALID': return vm_exception('INVALID OP', opcode=ops[-1][1]) for op, opcode, pushval in ops: if trace_vm: """ This diverges from normal logging, as we use the logging namespace only to decide which features get logged in 'eth.vm.op' i.e. tracing can not be activated by activating a sub like 'eth.vm.op.stack' """ trace_data = {} trace_data['stack'] = list( map(to_string, list(compustate.stack))) if _prevop in ('MLOAD', 'MSTORE', 'MSTORE8', 'SHA3', 'CALL', 'CALLCODE', 'CREATE', 'CALLDATACOPY', 'CODECOPY', 'EXTCODECOPY'): if len(compustate.memory) < 1024: trace_data['memory'] = \ ''.join([encode_hex(ascii_chr(x)) for x in compustate.memory]) else: trace_data['sha3memory'] = \ encode_hex(utils.sha3(b''.join([ascii_chr(x) for x in compustate.memory]))) if _prevop in ('SSTORE', ) or steps == 0: trace_data['storage'] = ext.log_storage(msg.to) trace_data['gas'] = to_string(compustate.gas + totgas) trace_data['inst'] = opcode trace_data['pc'] = to_string(compustate.pc - 1) if steps == 0: trace_data['depth'] = msg.depth trace_data['address'] = msg.to trace_data['steps'] = steps trace_data['depth'] = msg.depth if op[:4] == 'PUSH': trace_data['pushvalue'] = pushval log_vm_op.trace('vm', op=op, **trace_data) steps += 1 _prevop = op # Valid operations # Pushes first because they are very frequent if 0x60 <= opcode <= 0x7f: # compustate.pc += opcode - 0x5f # Move 1 byte forward for # 0x60, up to 32 bytes for 0x7f stk.append(pushval) elif opcode < 0x10: if op == 'STOP': return peaceful_exit('STOP', compustate.gas, []) elif op == 'ADD': stk.append((stk.pop() + stk.pop()) & TT256M1) elif op == 'SUB': stk.append((stk.pop() - stk.pop()) & TT256M1) elif op == 'MUL': stk.append((stk.pop() * stk.pop()) & TT256M1) elif op == 'DIV': s0, s1 = stk.pop(), stk.pop() stk.append(0 if s1 == 0 else s0 // s1) elif op == 'MOD': s0, s1 = stk.pop(), stk.pop() stk.append(0 if s1 == 0 else s0 % s1) elif op == 'SDIV': s0, s1 = utils.to_signed(stk.pop()), utils.to_signed( stk.pop()) stk.append(0 if s1 == 0 else (abs(s0) // abs(s1) * (-1 if s0 * s1 < 0 else 1)) & TT256M1) elif op == 'SMOD': s0, s1 = utils.to_signed(stk.pop()), utils.to_signed( stk.pop()) stk.append(0 if s1 == 0 else (abs(s0) % abs(s1) * (-1 if s0 < 0 else 1)) & TT256M1) elif op == 'ADDMOD': s0, s1, s2 = stk.pop(), stk.pop(), stk.pop() stk.append((s0 + s1) % s2 if s2 else 0) elif op == 'MULMOD': s0, s1, s2 = stk.pop(), stk.pop(), stk.pop() stk.append((s0 * s1) % s2 if s2 else 0) elif op == 'EXP': base, exponent = stk.pop(), stk.pop() # fee for exponent is dependent on its bytes # calc n bytes to represent exponent nbytes = len(utils.encode_int(exponent)) expfee = nbytes * opcodes.GEXPONENTBYTE if ext.post_clearing_hardfork(): expfee += opcodes.EXP_SUPPLEMENTAL_GAS * nbytes if compustate.gas < expfee: compustate.gas = 0 return vm_exception('OOG EXPONENT') compustate.gas -= expfee stk.append(pow(base, exponent, TT256)) elif op == 'SIGNEXTEND': s0, s1 = stk.pop(), stk.pop() if s0 <= 31: testbit = s0 * 8 + 7 if s1 & (1 << testbit): stk.append(s1 | (TT256 - (1 << testbit))) else: stk.append(s1 & ((1 << testbit) - 1)) else: stk.append(s1) elif opcode < 0x20: if op == 'LT': stk.append(1 if stk.pop() < stk.pop() else 0) elif op == 'GT': stk.append(1 if stk.pop() > stk.pop() else 0) elif op == 'SLT': s0, s1 = utils.to_signed(stk.pop()), utils.to_signed( stk.pop()) stk.append(1 if s0 < s1 else 0) elif op == 'SGT': s0, s1 = utils.to_signed(stk.pop()), utils.to_signed( stk.pop()) stk.append(1 if s0 > s1 else 0) elif op == 'EQ': stk.append(1 if stk.pop() == stk.pop() else 0) elif op == 'ISZERO': stk.append(0 if stk.pop() else 1) elif op == 'AND': stk.append(stk.pop() & stk.pop()) elif op == 'OR': stk.append(stk.pop() | stk.pop()) elif op == 'XOR': stk.append(stk.pop() ^ stk.pop()) elif op == 'NOT': stk.append(TT256M1 - stk.pop()) elif op == 'BYTE': s0, s1 = stk.pop(), stk.pop() if s0 >= 32: stk.append(0) else: stk.append((s1 // 256**(31 - s0)) % 256) elif opcode < 0x40: if op == 'SHA3': s0, s1 = stk.pop(), stk.pop() compustate.gas -= opcodes.GSHA3WORD * \ (utils.ceil32(s1) // 32) if compustate.gas < 0: return vm_exception('OOG PAYING FOR SHA3') if not mem_extend(mem, compustate, op, s0, s1): return vm_exception('OOG EXTENDING MEMORY') data = bytearray_to_bytestr(mem[s0:s0 + s1]) stk.append(utils.big_endian_to_int(utils.sha3(data))) elif op == 'ADDRESS': stk.append(utils.coerce_to_int(msg.to)) elif op == 'BALANCE': if ext.post_anti_dos_hardfork(): if not eat_gas(compustate, opcodes.BALANCE_SUPPLEMENTAL_GAS): return vm_exception("OUT OF GAS") addr = utils.coerce_addr_to_hex(stk.pop() % 2**160) stk.append(ext.get_balance(addr)) elif op == 'ORIGIN': stk.append(utils.coerce_to_int(ext.tx_origin)) elif op == 'CALLER': stk.append(utils.coerce_to_int(msg.sender)) elif op == 'CALLVALUE': stk.append(msg.value) elif op == 'CALLDATALOAD': stk.append(msg.data.extract32(stk.pop())) elif op == 'CALLDATASIZE': stk.append(msg.data.size) elif op == 'CALLDATACOPY': mstart, dstart, size = stk.pop(), stk.pop(), stk.pop() if not mem_extend(mem, compustate, op, mstart, size): return vm_exception('OOG EXTENDING MEMORY') if not data_copy(compustate, size): return vm_exception('OOG COPY DATA') msg.data.extract_copy(mem, mstart, dstart, size) elif op == 'CODESIZE': stk.append(len(code)) elif op == 'CODECOPY': mstart, dstart, size = stk.pop(), stk.pop(), stk.pop() if not mem_extend(mem, compustate, op, mstart, size): return vm_exception('OOG EXTENDING MEMORY') if not data_copy(compustate, size): return vm_exception('OOG COPY DATA') for i in range(size): if dstart + i < len(code): mem[mstart + i] = utils.safe_ord(code[dstart + i]) else: mem[mstart + i] = 0 elif op == 'RETURNDATACOPY': mstart, dstart, size = stk.pop(), stk.pop(), stk.pop() if not mem_extend(mem, compustate, op, mstart, size): return vm_exception('OOG EXTENDING MEMORY') if not data_copy(compustate, size): return vm_exception('OOG COPY DATA') if dstart + size > len(compustate.last_returned): return vm_exception('RETURNDATACOPY out of range') mem[mstart:mstart + size] = compustate.last_returned elif op == 'RETURNDATASIZE': stk.append(len(compustate.last_returned)) elif op == 'GASPRICE': stk.append(ext.tx_gasprice) elif op == 'EXTCODESIZE': if ext.post_anti_dos_hardfork(): if not eat_gas(compustate, opcodes.EXTCODELOAD_SUPPLEMENTAL_GAS): return vm_exception("OUT OF GAS") addr = utils.coerce_addr_to_hex(stk.pop() % 2**160) stk.append(len(ext.get_code(addr) or b'')) elif op == 'EXTCODECOPY': if ext.post_anti_dos_hardfork(): if not eat_gas(compustate, opcodes.EXTCODELOAD_SUPPLEMENTAL_GAS): return vm_exception("OUT OF GAS") addr = utils.coerce_addr_to_hex(stk.pop() % 2**160) start, s2, size = stk.pop(), stk.pop(), stk.pop() extcode = ext.get_code(addr) or b'' assert utils.is_string(extcode) if not mem_extend(mem, compustate, op, start, size): return vm_exception('OOG EXTENDING MEMORY') if not data_copy(compustate, size): return vm_exception('OOG COPY DATA') for i in range(size): if s2 + i < len(extcode): mem[start + i] = utils.safe_ord(extcode[s2 + i]) else: mem[start + i] = 0 elif opcode < 0x50: if op == 'BLOCKHASH': if ext.post_metropolis_hardfork() and False: bh_addr = ext.blockhash_store stk.append(ext.get_storage_data(bh_addr, stk.pop())) else: stk.append( utils.big_endian_to_int(ext.block_hash(stk.pop()))) elif op == 'COINBASE': stk.append(utils.big_endian_to_int(ext.block_coinbase)) elif op == 'TIMESTAMP': stk.append(ext.block_timestamp) elif op == 'NUMBER': stk.append(ext.block_number) elif op == 'DIFFICULTY': stk.append(ext.block_difficulty) elif op == 'GASLIMIT': stk.append(ext.block_gas_limit) elif opcode < 0x60: if op == 'POP': stk.pop() elif op == 'MLOAD': s0 = stk.pop() if not mem_extend(mem, compustate, op, s0, 32): return vm_exception('OOG EXTENDING MEMORY') stk.append(utils.bytes_to_int(mem[s0:s0 + 32])) elif op == 'MSTORE': s0, s1 = stk.pop(), stk.pop() if not mem_extend(mem, compustate, op, s0, 32): return vm_exception('OOG EXTENDING MEMORY') mem[s0:s0 + 32] = utils.encode_int32(s1) elif op == 'MSTORE8': s0, s1 = stk.pop(), stk.pop() if not mem_extend(mem, compustate, op, s0, 1): return vm_exception('OOG EXTENDING MEMORY') mem[s0] = s1 % 256 elif op == 'SLOAD': if ext.post_anti_dos_hardfork(): if not eat_gas(compustate, opcodes.SLOAD_SUPPLEMENTAL_GAS): return vm_exception("OUT OF GAS") stk.append(ext.get_storage_data(msg.to, stk.pop())) elif op == 'SSTORE': s0, s1 = stk.pop(), stk.pop() if msg.static: return vm_exception( 'Cannot SSTORE inside a static context') if ext.get_storage_data(msg.to, s0): gascost = opcodes.GSTORAGEMOD if s1 else opcodes.GSTORAGEKILL refund = 0 if s1 else opcodes.GSTORAGEREFUND else: gascost = opcodes.GSTORAGEADD if s1 else opcodes.GSTORAGEMOD refund = 0 if compustate.gas < gascost: return vm_exception('OUT OF GAS') compustate.gas -= gascost # adds neg gascost as a refund if below zero ext.add_refund(refund) ext.set_storage_data(msg.to, s0, s1) elif op == 'JUMP': compustate.pc = stk.pop() opnew = code[ compustate.pc] if compustate.pc < codelen else 0 jumped = True if opnew != JUMPDEST: return vm_exception('BAD JUMPDEST') elif op == 'JUMPI': s0, s1 = stk.pop(), stk.pop() if s1: compustate.pc = s0 opnew = code[ compustate.pc] if compustate.pc < codelen else 0 jumped = True if opnew != JUMPDEST: return vm_exception('BAD JUMPDEST') elif op == 'PC': stk.append(compustate.pc - 1) elif op == 'MSIZE': stk.append(len(mem)) elif op == 'GAS': stk.append(compustate.gas) # AFTER subtracting cost 1 elif op[:3] == 'DUP': # 0x7f - opcode is a negative number, -1 for 0x80 ... -16 for # 0x8f stk.append(stk[0x7f - opcode]) elif op[:4] == 'SWAP': # 0x8e - opcode is a negative number, -2 for 0x90 ... -17 for # 0x9f temp = stk[0x8e - opcode] stk[0x8e - opcode] = stk[-1] stk[-1] = temp elif op[:3] == 'LOG': """ 0xa0 ... 0xa4, 32/64/96/128/160 + len(data) gas a. Opcodes LOG0...LOG4 are added, takes 2-6 stack arguments MEMSTART MEMSZ (TOPIC1) (TOPIC2) (TOPIC3) (TOPIC4) b. Logs are kept track of during tx execution exactly the same way as suicides (except as an ordered list, not a set). Each log is in the form [address, [topic1, ... ], data] where: * address is what the ADDRESS opcode would output * data is mem[MEMSTART: MEMSTART + MEMSZ] * topics are as provided by the opcode c. The ordered list of logs in the transaction are expressed as [log0, log1, ..., logN]. """ depth = int(op[3:]) mstart, msz = stk.pop(), stk.pop() topics = [stk.pop() for x in range(depth)] compustate.gas -= msz * opcodes.GLOGBYTE if msg.static: return vm_exception('Cannot LOG inside a static context') if not mem_extend(mem, compustate, op, mstart, msz): return vm_exception('OOG EXTENDING MEMORY') data = bytearray_to_bytestr(mem[mstart:mstart + msz]) ext.log(msg.to, topics, data) log_log.trace('LOG', to=msg.to, topics=topics, data=list(map(utils.safe_ord, data))) # print('LOG', msg.to, topics, list(map(ord, data))) elif op == 'CREATE': value, mstart, msz = stk.pop(), stk.pop(), stk.pop() if not mem_extend(mem, compustate, op, mstart, msz): return vm_exception('OOG EXTENDING MEMORY') if msg.static: return vm_exception( 'Cannot CREATE inside a static context') if ext.get_balance(msg.to) >= value and msg.depth < MAX_DEPTH: cd = CallData(mem, mstart, msz) ingas = compustate.gas if ext.post_anti_dos_hardfork(): ingas = all_but_1n(ingas, opcodes.CALL_CHILD_LIMIT_DENOM) create_msg = Message(msg.to, b'', value, ingas, cd, msg.depth + 1) o, gas, addr = ext.create(create_msg) if o: stk.append(utils.coerce_to_int(addr)) else: stk.append(0) compustate.gas = compustate.gas - ingas + gas else: stk.append(0) elif op in ('CALL', 'CALLCODE', 'DELEGATECALL', 'STATICCALL'): # Pull arguments from the stack if op in ('CALL', 'CALLCODE'): gas, to, value, meminstart, meminsz, memoutstart, memoutsz = \ stk.pop(), stk.pop(), stk.pop(), stk.pop(), stk.pop(), stk.pop(), stk.pop() else: gas, to, meminstart, meminsz, memoutstart, memoutsz = \ stk.pop(), stk.pop(), stk.pop(), stk.pop(), stk.pop(), stk.pop() value = 0 # Static context prohibition if msg.static and value > 0: return vm_exception( 'Cannot make a non-zero-value call inside a static context' ) # Expand memory if not mem_extend(mem, compustate, op, meminstart, meminsz) or \ not mem_extend(mem, compustate, op, memoutstart, memoutsz): return vm_exception('OOG EXTENDING MEMORY') to = utils.int_to_addr(to) # Extra gas costs based on hard fork-dependent factors extra_gas = (not ext.account_exists(to)) * (op == 'CALL') * (value > 0 or not ext.post_clearing_hardfork()) * opcodes.GCALLNEWACCOUNT + \ (value > 0) * opcodes.GCALLVALUETRANSFER + \ ext.post_anti_dos_hardfork() * opcodes.CALL_SUPPLEMENTAL_GAS # Compute child gas limit if ext.post_anti_dos_hardfork(): if compustate.gas < extra_gas: return vm_exception('OUT OF GAS', needed=extra_gas) gas = min( gas, all_but_1n(compustate.gas - extra_gas, opcodes.CALL_CHILD_LIMIT_DENOM)) else: if compustate.gas < gas + extra_gas: return vm_exception('OUT OF GAS', needed=gas + extra_gas) submsg_gas = gas + opcodes.GSTIPEND * (value > 0) # Verify that there is sufficient balance and depth if ext.get_balance(msg.to) < value or msg.depth >= MAX_DEPTH: compustate.gas -= (gas + extra_gas - submsg_gas) stk.append(0) else: # Subtract gas from parent compustate.gas -= (gas + extra_gas) assert compustate.gas >= 0 cd = CallData(mem, meminstart, meminsz) # Generate the message if op == 'CALL': call_msg = Message(msg.to, to, value, submsg_gas, cd, msg.depth + 1, code_address=to, static=msg.static) elif ext.post_homestead_hardfork( ) and op == 'DELEGATECALL': call_msg = Message(msg.sender, msg.to, msg.value, submsg_gas, cd, msg.depth + 1, code_address=to, transfers_value=False, static=msg.static) elif op == 'DELEGATECALL': return vm_exception('OPCODE INACTIVE') elif op == 'CALLCODE': call_msg = Message(msg.to, msg.to, value, submsg_gas, cd, msg.depth + 1, code_address=to, static=msg.static) elif op == 'STATICCALL': call_msg = Message(msg.to, to, value, submsg_gas, cd, msg.depth + 1, code_address=to, static=True) else: raise Exception("Lolwut") # Get result result, gas, data = ext.msg(call_msg) if result == 0: stk.append(0) else: stk.append(1) # Set output memory for i in range(min(len(data), memoutsz)): mem[memoutstart + i] = data[i] compustate.gas += gas compustate.last_returned = bytearray(data) elif op == 'RETURN': s0, s1 = stk.pop(), stk.pop() if not mem_extend(mem, compustate, op, s0, s1): return vm_exception('OOG EXTENDING MEMORY') return peaceful_exit('RETURN', compustate.gas, mem[s0:s0 + s1]) elif op == 'REVERT': if not ext.post_metropolis_hardfork(): return vm_exception('Opcode not yet enabled') s0, s1 = stk.pop(), stk.pop() if not mem_extend(mem, compustate, op, s0, s1): return vm_exception('OOG EXTENDING MEMORY') return revert(compustate.gas, mem[s0:s0 + s1]) elif op == 'SUICIDE': if msg.static: return vm_exception( 'Cannot SUICIDE inside a static context') to = utils.encode_int(stk.pop()) to = ((b'\x00' * (32 - len(to))) + to)[12:] xfer = ext.get_balance(msg.to) if ext.post_anti_dos_hardfork(): extra_gas = opcodes.SUICIDE_SUPPLEMENTAL_GAS + \ (not ext.account_exists( to)) * (xfer > 0 or not ext.post_clearing_hardfork()) * opcodes.GCALLNEWACCOUNT if not eat_gas(compustate, extra_gas): return vm_exception("OUT OF GAS") ext.set_balance(to, ext.get_balance(to) + xfer) ext.set_balance(msg.to, 0) ext.add_suicide(msg.to) log_msg.debug('SUICIDING', addr=utils.checksum_encode(msg.to), to=utils.checksum_encode(to), xferring=xfer) return 1, compustate.gas, [] # assert utils.is_numeric(compustate.gas) # this is slow! # for a in stk: # assert is_numeric(a), (op, stk) # assert a >= 0 and a < 2**256, (a, op, stk) # if not jumped: # assert compustate.pc == nextpos # compustate.pc = nextpos if compustate.pc >= codelen: return peaceful_exit('CODE OUT OF RANGE', compustate.gas, []) return vm_exception('INVALID JUMP')
from ethereum.tools import tester as t from ethereum import utils as u c = t.Chain() x = c.contract(open('utxos.v.py').read(), language='viper', sender=t.k0) assert u.normalize_address(x.get_utxos__owner(u.encode_int32(1))) == t.a0 assert x.get_utxos__value(u.encode_int32(1)) == 2**32 sigdata = u.encode_int32(1) + u.encode_int32(0) + b'\x00' * 12 + t.a2 + \ u.encode_int32(2**30) + b'\x00' * 12 + t.a2 + u.encode_int32(3 * 2**30) sighash = u.sha3(sigdata) v, r, s = u.ecsign(sighash, t.k0) assert x.tx(u.encode_int32(1), u.encode_int32(0), t.a2, 2**30, t.a2, 3 * 2**30, v, r, s) == sighash assert u.normalize_address(x.get_utxos__owner(sighash)) == t.a2 assert x.get_utxos__value(sighash) == 2**30 sigdata2 = sighash + u.encode_int32(0) + b'\x00' * 12 + t.a3 + \ u.encode_int32(2**29) + b'\x00' * 12 + t.a3 + u.encode_int32(2**29) sighash2 = u.sha3(sigdata2) v, r, s = u.ecsign(sighash2, t.k2) assert x.tx(sighash, u.encode_int32(0), t.a3, 2**29, t.a3, 2**29, v, r, s) == sighash2 print('Tests passed')
def sign(hash, key): vrs = u.ecsign(hash, key) rsv = vrs[1:] + vrs[:1] vrs_bytes = [u.encode_int32(i) for i in rsv[:2]] + [u.int_to_bytes(rsv[2])] return b''.join(vrs_bytes)
def sign(msg_hash, privkey): v, r, s = utils.ecsign(msg_hash, privkey) signature = utils.encode_int32(v) + utils.encode_int32( r) + utils.encode_int32(s) return signature
def mk_modexp_data(b, e, m): benc = int_to_big_endian(b) eenc = int_to_big_endian(e) menc = int_to_big_endian(m) return encode_int32(len(benc)) + encode_int32(len(eenc)) + encode_int32( len(menc)) + benc + eenc + menc
def mk_commit(epoch, hash, key): sighash = utils.sha3(rlp.encode([epoch, hash])) v, r, s = utils.ecdsa_raw_sign(sighash, key) sig = utils.encode_int32(v) + utils.encode_int32(r) + utils.encode_int32(s) return rlp.encode([epoch, hash, sig])
def mk_logout(validator_index, epoch, key): sighash = utils.sha3(rlp.encode([validator_index, epoch])) v, r, s = utils.ecdsa_raw_sign(sighash, key) sig = utils.encode_int32(v) + utils.encode_int32(r) + utils.encode_int32(s) return rlp.encode([validator_index, epoch, sig])
def mk_prepare(validator_index, epoch, ancestry_hash, source_epoch, source_ancestry_hash, key): sighash = utils.sha3(rlp.encode([validator_index, epoch, ancestry_hash, source_epoch, source_ancestry_hash])) v, r, s = utils.ecdsa_raw_sign(sighash, key) sig = utils.encode_int32(v) + utils.encode_int32(r) + utils.encode_int32(s) return rlp.encode([validator_index, epoch, ancestry_hash, source_epoch, source_ancestry_hash, sig])
def eth_pubtoaddr(self, x, y): return u.checksum_encode( u.sha3(u.encode_int32(x) + u.encode_int32(y))[12:]).lower()
def mk_logout_msg_unsigned(validator_index, epoch): v, r, s = (0, 0, 0) sig = utils.encode_int32(v) + utils.encode_int32( r) + utils.encode_int32(s) return rlp.encode([validator_index, epoch, sig])
def make_withdrawal_signature(key): h = sha3(b'withdrawwithdrawwithdrawwithdraw') v, r, s = ecsign(h, key) return encode_int32(v) + encode_int32(r) + encode_int32(s)
def mk_status_flicker(validator_index, epoch, login, key): sighash = utils.sha3(rlp.encode([validator_index, epoch, login])) v, r, s = utils.ecdsa_raw_sign(sighash, key) sig = utils.encode_int32(v) + utils.encode_int32(r) + utils.encode_int32(s) return rlp.encode([validator_index, epoch, login, sig])
def test_validator_manager(): # Must pay 100 ETH to become a validator c = t.Chain(env='sharding', deploy_sharding_contracts=True) k0_valcode_addr = c.tx(t.k0, '', 0, mk_validation_code(t.a0)) k1_valcode_addr = c.tx(t.k1, '', 0, mk_validation_code(t.a1)) num_blocks = 11 c.mine(num_blocks - 1, coinbase=t.a0) c.head_state.gas_limit = 10 ** 12 # deploy valmgr and its prerequisite contracts and transactions x = t.ABIContract(c, get_valmgr_ct(), get_valmgr_addr()) # test deposit: fails when msg.value != DEPOSIT_SIZE with pytest.raises(t.TransactionFailed): # gas == GASLIMIT x.deposit(k0_valcode_addr, k0_valcode_addr) # test withdraw: fails when no validator record assert not x.withdraw(0, sign(WITHDRAW_HASH, t.k0)) # test deposit: works fine return_addr = utils.privtoaddr(utils.sha3("return_addr")) assert 0 == x.deposit(k0_valcode_addr, return_addr, value=DEPOSIT_SIZE, sender=t.k0) assert 1 == x.deposit(k1_valcode_addr, return_addr, value=DEPOSIT_SIZE, sender=t.k1) assert x.withdraw(0, sign(WITHDRAW_HASH, t.k0)) # test withdraw: see if the money is returned assert c.head_state.get_balance(return_addr) == DEPOSIT_SIZE # test deposit: make use of empty slots assert 0 == x.deposit(k0_valcode_addr, return_addr, value=DEPOSIT_SIZE, sender=t.k0) assert x.withdraw(1, sign(WITHDRAW_HASH, t.k1)) # test deposit: working fine in the edge condition assert 1 == x.deposit(k1_valcode_addr, return_addr, value=DEPOSIT_SIZE, sender=t.k1) # test deposit: fails when valcode_addr is deposited before with pytest.raises(t.TransactionFailed): x.deposit(k1_valcode_addr, return_addr, value=DEPOSIT_SIZE, sender=t.k1) # test withdraw: fails when the signature is not corret assert not x.withdraw(1, sign(WITHDRAW_HASH, t.k0)) # test sample: correctly sample the only one validator assert x.withdraw(0, sign(WITHDRAW_HASH, t.k0)) assert x.sample(0) == hex(utils.big_endian_to_int(k1_valcode_addr)) # test sample: sample returns zero_addr (i.e. 0x00) when there is no depositing validator assert x.withdraw(1, sign(WITHDRAW_HASH, t.k1)) assert x.sample(0) == "0x0000000000000000000000000000000000000000" def get_colhdr(shard_id, parent_collation_hash, collation_coinbase=t.a0): period_length = 5 expected_period_number = num_blocks // period_length b = c.chain.get_block_by_number(expected_period_number * period_length - 1) period_start_prevhash = b.header.hash tx_list_root = b"tx_list " * 4 post_state_root = b"post_sta" * 4 receipt_root = b"receipt " * 4 sighash = utils.sha3( rlp.encode([ shard_id, expected_period_number, period_start_prevhash, parent_collation_hash, tx_list_root, collation_coinbase, post_state_root, receipt_root ]) ) sig = sign(sighash, t.k0) return rlp.encode([ shard_id, expected_period_number, period_start_prevhash, parent_collation_hash, tx_list_root, collation_coinbase, post_state_root, receipt_root, sig ]) header_logs = [] add_header_topic = utils.big_endian_to_int(utils.sha3("add_header()")) def header_event_watcher(log): header_logs, add_header_topic # print the last log and store the recent received one if log.topics[0] == add_header_topic: # print(log.data) header_logs.append(log.data) if len(header_logs) > 1: last_log = header_logs.pop(0) # [num, num, bytes32, bytes32, bytes32, address, bytes32, bytes32, bytes] # use sedes to prevent integer 0 from being decoded as b'' sedes = List([utils.big_endian_int, utils.big_endian_int, utils.hash32, utils.hash32, utils.hash32, utils.address, utils.hash32, utils.hash32, binary]) values = rlp.decode(last_log, sedes) print("add_header: shard_id={}, expected_period_number={}, header_hash={}, parent_header_hash={}".format(values[0], values[1], utils.sha3(last_log), values[3])) c.head_state.log_listeners.append(header_event_watcher) shard_id = 0 shard0_genesis_colhdr_hash = utils.encode_int32(0) # test get_shard_head: returns genesis_colhdr_hash when there is no new header assert x.get_shard_head() == shard0_genesis_colhdr_hash h1 = get_colhdr(shard_id, shard0_genesis_colhdr_hash) h1_hash = utils.sha3(h1) # test add_header: fails when there is no collator in this period assert not x.add_header(h1) assert 1 == x.deposit(k0_valcode_addr, return_addr, value=DEPOSIT_SIZE, sender=t.k0) # test add_header: works normally with parent_collation_hash == GENESIS assert x.add_header(h1) # test add_header: fails when the header is added before with pytest.raises(t.TransactionFailed): h1 = get_colhdr(shard_id, shard0_genesis_colhdr_hash) x.add_header(h1) # test add_header: fails when the parent_collation_hash is not added before with pytest.raises(t.TransactionFailed): h2 = get_colhdr(shard_id, utils.sha3("123")) x.add_header(h2) # test add_header: the log is generated normally h2 = get_colhdr(shard_id, h1_hash) h2_hash = utils.sha3(h2) assert x.add_header(h2) latest_log_hash = utils.sha3(header_logs[-1]) assert h2_hash == latest_log_hash # test get_shard_head: get the correct head when a new header is added assert x.get_shard_head(0) == h2_hash # test get_shard_head: get the correct head when a fork happened h1_prime = get_colhdr(shard_id, shard0_genesis_colhdr_hash, collation_coinbase=t.a1) h1_prime_hash = utils.sha3(h1_prime) assert x.add_header(h1_prime) h2_prime = get_colhdr(shard_id, h1_prime_hash, collation_coinbase=t.a1) h2_prime_hash = utils.sha3(h2_prime) assert x.add_header(h2_prime) assert x.get_shard_head(0) == h2_hash h3_prime = get_colhdr(shard_id, h2_prime_hash, collation_coinbase=t.a1) h3_prime_hash = utils.sha3(h3_prime) assert x.add_header(h3_prime) assert x.get_shard_head(0) == h3_prime_hash ''' # test get_ancestor: h3_prime's height is too low so and it doesn't have a # 10000th ancestor. So it should fail. with pytest.raises(t.TransactionFailed): ancestor_10000th_hash = x.get_ancestor(shard_id, h3_prime_hash) # test get_ancestor: # TODO: figure out a better test instead of adding headers one by one. # This test takes few minutes. For now, you can adjust the `kth_ancestor` # to a smaller number here, and the same number of iterations of the `for` # loop in `get_ancestor` in the validator_manager contract. current_height = 3 # h3_prime kth_ancestor = 10000 current_colhdr_hash = h3_prime_hash # add (kth_ancestor - current_height) headers to get the genesis as the ancestor for i in range(kth_ancestor - current_height): current_colhdr = get_colhdr(shard_id, current_colhdr_hash, collation_coinbase=t.a1) assert x.add_header(current_colhdr) current_colhdr_hash = utils.sha3(current_colhdr) assert x.get_ancestor(shard_id, current_colhdr_hash) == shard0_genesis_colhdr_hash ''' # test tx_to_shard: add request tx and get the receipt id to_addr = utils.privtoaddr(utils.sha3("to_addr")) startgas = 100000 gasprice = 1 receipt_id0 = x.tx_to_shard(to_addr, 0, startgas, gasprice, b'', sender=t.k0, value=100) assert 0 == receipt_id0 # test tx_to_shard: see if receipt_id is incrementing when called # multiple times receipt_id1 = x.tx_to_shard(to_addr, 0, startgas, gasprice, b'', sender=t.k1, value=101) assert 1 == receipt_id1 assert 101 == x.get_receipts__value(receipt_id1) # test update_gasprice: fails when msg.sender doesn't match with pytest.raises(t.TransactionFailed): x.update_gasprice(receipt_id1, 2, sender=t.k0) # test update_gasprice: see if the gasprice updated successfully assert x.update_gasprice(receipt_id1, 2, sender=t.k1) assert 2 == x.get_receipts__tx_gasprice(receipt_id1) print(utils.checksum_encode(get_valmgr_addr()))
def sign(_hash, key): v, r, s = utils.ecsign(_hash, key) return utils.encode_int32(r) + utils.encode_int32(s) + utils.encode_int(v)
def sign(hash, privkey): assert len(privkey) == 32 v, r, s = ecsign(hash, privkey) return encode_int32(v) + encode_int32(r) + encode_int32(s)
value=0, gas=1000000, data=data) print("Setting block hashes") for i in range(1, 1000): s.state.block_number = i + 1 o = apply_message(s.state, mk_hash_setting_message(sha3(str(i)))) if i % 100 == 0: print("Set %d" % i) print("Testing reads") s.state.block_number = 1000 assert s.send(tester.k0, blockhash_addr, 0, encode_int32(999)) == sha3(str(999)) assert s.send(tester.k0, blockhash_addr, 0, encode_int32(998)) == sha3(str(998)) assert s.send(tester.k0, blockhash_addr, 0, encode_int32(744)) == sha3(str(744)) assert s.send(tester.k0, blockhash_addr, 0, encode_int32(743)) == b'\x00' * 32 assert s.send(tester.k0, blockhash_addr, 0, encode_int32(1000)) == b'\x00' * 32 assert s.send(tester.k0, blockhash_addr, 0, encode_int32(1001)) == b'\x00' * 32 assert s.send(tester.k0, blockhash_addr, 0, encode_int32(513)) == b'\x00' * 32 assert s.send(tester.k0, blockhash_addr, 0, encode_int32(512)) == sha3(str(512)) assert s.send(tester.k0, blockhash_addr, 0, encode_int32(511)) == b'\x00' * 32 assert s.send(tester.k0, blockhash_addr, 0, encode_int32(256)) == sha3(str(256)) print("Tests passed!")
casper.initialize_epoch(3) assert casper.get_total_curdyn_deposits() == 200 * 10**18 assert casper.get_total_prevdyn_deposits() == 0 _e, _a, _se, _sa = \ casper.get_current_epoch(), casper.get_recommended_ancestry_hash(), \ casper.get_recommended_source_epoch(), casper.get_recommended_source_ancestry_hash() print("Penalty factor: %.8f" % (casper.get_current_penalty_factor())) # Send a prepare message print('pre deposit', casper.get_deposit_size(0), casper.get_total_curdyn_deposits()) assert casper.get_deposit_size(0) == casper.get_total_curdyn_deposits() casper.prepare(mk_prepare(0, _e, _a, _se, _sa, t.k1)) print('Gas consumed for a prepare: %d' % s.last_gas_used(with_tx=True)) sourcing_hash = utils.sha3( utils.encode_int32(_e) + _a + utils.encode_int32(_se) + _sa) assert casper.get_consensus_messages__ancestry_hash_justified(_e, _a) assert casper.get_main_hash_justified() print("Prepare message processed") try: casper.prepare( mk_prepare(0, 1, '\x35' * 32, '\x00' * 32, 0, '\x00' * 32, t.k0)) success = True except: success = False assert not success print("Prepare message fails the second time") # Send a commit message casper.commit(mk_commit(0, _e, _a, 0, t.k1)) print('post deposit', casper.get_deposit_size(0)) print('Gas consumed for a commit: %d' % s.last_gas_used(with_tx=True))
def perturb(inp, pos, by): return inp[:pos] + \ encode_int32(big_endian_to_int( inp[pos: pos + 32]) + by) + inp[pos + 32:]
zero_address = "0x0000000000000000000000000000000000000000" accounts = [ "0x776ba14735ff84789320718cf0aa43e91f7a8ce1", "0x095ce4e4240fa66ff90282c26847456e3f3b5002" ] recipient = "0x776ba14735ff84789320718cf0aa43e91f7a8ce1" raw_sigs = [ "0x4a89507bf71749fb338ed13fba623a683d9ecab0fb9c389a4298525c043e38281a00ab65628bb18a382eb8c8b4fb4dae95ccc993cf49f617c60d8051180778601c", "0xc84fe5d2a600e033930e0cf73f26e78f4c65b134f9c9992f60f08ce0863abdbe0548a6e8aa2d952659f29c67106b59fdfcd64d67df03c1df620c70c85578ae701b" ] sigs = [(utils.big_endian_to_int(x[64:]), utils.big_endian_to_int(x[:32]), utils.big_endian_to_int(x[32:64])) for x in map(lambda z: utils.decode_hex(z[2:]), raw_sigs)] h = utils.sha3( utils.encode_int32(0) + b'\x00' * 12 + utils.decode_hex(recipient[2:]) + utils.encode_int32(25) + b'') h2 = utils.sha3(b"\x19Ethereum Signed Message:\n32" + h) assert '0x' + utils.encode_hex( utils.sha3(utils.ecrecover_to_pub(h2, sigs[0][0], sigs[0][1], sigs[0][2]))[12:]) == accounts[0] assert '0x' + utils.encode_hex( utils.sha3(utils.ecrecover_to_pub(h2, sigs[1][0], sigs[1][1], sigs[1][2]))[12:]) == accounts[1] x2 = c.contract(open('wallet.v.py').read(), args=[accounts + [t.a3, zero_address, zero_address], 2], language='viper') c.tx(sender=t.k1, to=x2.address, value=10**17)
def sign(seq, to, value, data, key): h1 = utils.sha3(utils.encode_int32(seq) + b'\x00' * 12 + to + utils.encode_int32(value) + data) h2 = utils.sha3(b"\x19Ethereum Signed Message:\n32" + h1) return list(utils.ecsign(h2, key))
print("Epoch initialized") # Deposit one validator induct_validator(casper, t.k1, 200 * 10**18) # Mine two epochs current_dyn, _e, _a, _se, _sa = new_epoch(s, casper, EPOCH_LENGTH) current_dyn, _e, _a, _se, _sa = new_epoch(s, casper, EPOCH_LENGTH) assert casper.get_total_curdyn_deposits() == 200 * 10**18 assert casper.get_total_prevdyn_deposits() == 0 # Send a prepare message print('pre deposit', casper.get_deposit_size(0), casper.get_total_curdyn_deposits()) assert casper.get_deposit_size(0) == casper.get_total_curdyn_deposits() casper.prepare(mk_prepare(0, _e, _a, _se, _sa, t.k1)) print('Gas consumed for a prepare: %d' % s.last_gas_used(with_tx=True)) sourcing_hash = utils.sha3(utils.encode_int32(_e) + _a + utils.encode_int32(_se) + _sa) assert casper.get_consensus_messages__ancestry_hash_justified(_e, _a) assert casper.get_main_hash_justified() print("Prepare message processed") try: casper.prepare(mk_prepare(0, 1, '\x35' * 32, '\x00' * 32, 0, '\x00' * 32, t.k0)) success = True except: success = False assert not success print("Prepare message fails the second time") # Send a commit message casper.commit(mk_commit(0, _e, _a, 0, t.k1)) print('post deposit', casper.get_deposit_size(0)) print('Gas consumed for a commit: %d' % s.last_gas_used(with_tx=True)) # Check that we committed