From f1208195f4ebe58d270aefe489ae3bdd7208873e Mon Sep 17 00:00:00 2001 From: Vitalik Buterin Date: Tue, 7 Jan 2014 12:40:49 -0500 Subject: [PATCH] Updated trie format and stack language --- processblock.py | 49 ++++++++++++++++++++++++++----------------------- transactions.py | 6 +++--- trie.py | 29 ++++++++++++++++++----------- 3 files changed, 47 insertions(+), 37 deletions(-) diff --git a/processblock.py b/processblock.py index 4596162f76..a681a5970c 100644 --- a/processblock.py +++ b/processblock.py @@ -58,23 +58,27 @@ scriptcode_map = { } params = { - 'stepfee': 10**16, - 'txfee': 2**64, - 'newcontractfee': 2**64, - 'memoryfee': 2**64 / 4, - 'datafee': 2**64 / 16, - 'cryptofee': 2**64 / 16, - 'extrofee': 2**64 / 16, + 'stepfee': 1, + 'txfee': 100, + 'newcontractfee': 100, + 'memoryfee': 20, + 'datafee': 4, + 'cryptofee': 10, + 'extrofee': 10, 'blocktime': 60, - 'period_1_reward': 2**80 * 1024, + 'period_1_reward': 10**18 * 800, 'period_1_duration': 57600, - 'period_2_reward': 2**80 * 512, + 'period_2_reward': 10**18 * 400, 'period_2_duration': 57600, - 'period_3_reward': 2**80 * 256, + 'period_3_reward': 10**18 * 100, 'period_3_duration': 57600, - 'period_4_reward': 2**80 * 128 + 'period_4_reward': 10**18 * 50 } +def getfee(block,t): + if t in ['stepfee','txfee','newcontractfee','memoryfee','datafee','cryptofee','extrofee']: + return int(10**24 / int(block.difficulty ** 0.5)) * params[t] + def process_transactions(block,transactions): while len(transactions) > 0: tx = transactions.pop(0) @@ -85,9 +89,9 @@ def process_transactions(block,transactions): tdata = rlp.decode(block.state.get(tx.to)) or [0,0,0] # Calculate fee if tx.to == '\x00'*20: - fee = params['newcontractfee'] + len(tx.data) * params['memoryfee'] + fee = getfee('newcontractfee') + len(tx.data) * getfee('memoryfee') else: - fee = params['txfee'] + fee = getfee('txfee') # Insufficient fee, do nothing if fee > tx.fee: sys.stderr.write("Insufficient fee\n") @@ -143,11 +147,10 @@ def eval(block,transactions,timestamp,coinbase): reward = params['period_3_reward'] else: reward = params['period_4_reward'] - print reward miner_state[1] += reward + block.reward for uncle in block.uncles: sib_miner_state = rlp_decode(block.state.get(uncle[3])) - sib_miner_state[1] = encode(decode(sib_miner_state[1],256)+reward*7/8,256) + sib_miner_state[1] += reward*7/8 block.state.update(uncle[3],sib_miner_state) miner_state[1] += reward/8 block.state.update(block.coinbase,rlp.encode(miner_state)) @@ -190,18 +193,18 @@ def eval_contract(block,transaction_list,tx): nullfee = 0 stepcounter += 1 if stepcounter > 16: - minerfee += params["stepfee"] + minerfee += getfee("stepfee") c = scriptcode_map[code[0]] if c in ['STORE','LOAD']: - minerfee += params["datafee"] + minerfee += getfee("datafee") if c in ['EXTRO','BALANCE']: - minerfee += params["extrofee"] + minerfee += getfee("extrofee") if c in ['SHA256','RIPEMD-160','ECMUL','ECADD','ECSIGN','ECRECOVER']: - minerfee += params["cryptofee"] + minerfee += getfee("cryptofee") if c == 'STORE': existing = block.get_contract_state(address,code[2]) - if reg[code[1]] != 0: nullfee += params["memoryfee"] - if existing: nullfee -= params["memoryfee"] + if reg[code[1]] != 0: nullfee += getfee("memoryfee") + if existing: nullfee -= getfee("memoryfee") # If we can't pay the fee, break, otherwise pay it if block.get_balance(address) < minerfee + nullfee: @@ -356,7 +359,7 @@ def eval_contract(block,transaction_list,tx): elif code == 'SWAP': x,y = stack_pop(2) stack.extend([y,x]) - elif code = 'SWAPN': + elif code == 'SWAPN': arr = stack_pop(contract.get(encode(index + 1,256,32))) arr.append(arr[0]) arr.pop(0) @@ -393,7 +396,7 @@ def eval_contract(block,transaction_list,tx): transaction_list.insert(0,tx) elif code == 'SUICIDE': sz = contract.get_size() - negfee = -sz * params["memoryfee"] + negfee = -sz * getfee("memoryfee") toaddress = encode(stack_pop(1)[0],256,20) block.pay_fee(toaddress,negfee,False) contract.root = '' diff --git a/transactions.py b/transactions.py index c7985bcb99..1cd1d74512 100644 --- a/transactions.py +++ b/transactions.py @@ -17,12 +17,12 @@ class Transaction(): def parse(self,data): if re.match('^[0-9a-fA-F]*$',data): data = data.decode('hex') - o = rlp.unparse(data) + o = rlp.decode(data) self.nonce = o[0] self.to = o[1] self.value = o[2] self.fee = o[3] - self.data = rlp.decode(o[4]) + self.data = o[4] self.v = o[5] self.r = o[6] self.s = o[7] @@ -32,7 +32,7 @@ class Transaction(): return self def sign(self,key): - rawhash = sha256(rlp.encode([self.to,self.value,self.fee,self.data])) + rawhash = sha256(rlp.encode([self.nonce,self.to,self.value,self.fee,self.data])) self.v,self.r,self.s = ecdsa_raw_sign(rawhash,key) self.sender = bin_sha256(privtopub(key)[1:])[-20:] return self diff --git a/trie.py b/trie.py index d914f88d4a..c5cc7e563a 100644 --- a/trie.py +++ b/trie.py @@ -1,8 +1,8 @@ import leveldb import rlp -import hashlib +from sha3 import sha3_256 -def sha256(x): return hashlib.sha256(x).digest() +def sha3(x): return sha3_256(x).digest() class DB(): def __init__(self,dbfile): self.db = leveldb.LevelDB(dbfile) @@ -45,7 +45,7 @@ class Trie(): if self.debug: print 'nk',node.encode('hex'),key if len(key) == 0 or not node: return node - curnode = rlp.decode(self.db.get(node)) + curnode = rlp.decode(self.__lookup(node)) if self.debug: print 'cn', curnode if not curnode: raise Exception("node not found in database") @@ -61,10 +61,17 @@ class Trie(): def __put(self,node): rlpnode = rlp.encode(node) - h = sha256(rlpnode) - self.db.put(h,rlpnode) + if len(rlpnode) >= 32: + h = sha3(rlpnode) + self.db.put(h,rlpnode) + else: + h = rlpnode return h + def __lookup(self,node): + if len(node) < 32: return node + else: return self.db.get(node) + def __update_state(self,node,key,value): if value != '': return self.__insert_state(node,key,value) else: return self.__delete_state(node,key) @@ -77,7 +84,7 @@ class Trie(): if not node: newnode = [ hexarraykey_to_bin(key), value ] return self.__put(newnode) - curnode = rlp.decode(self.db.get(node)) + curnode = rlp.decode(self.__lookup(node)) if self.debug: print 'icn', curnode if not curnode: raise Exception("node not found in database") @@ -114,7 +121,7 @@ class Trie(): if len(key) == 0 or not node: return '' else: - curnode = rlp.decode(self.db.get(node)) + curnode = rlp.decode(self.__lookup(node)) if not curnode: raise Exception("node not found in database") if self.debug: print 'dcn', curnode @@ -125,7 +132,7 @@ class Trie(): return '' elif key[:len(k2)] == k2: newhash = self.__delete_state(v2,key[len(k2):]) - childnode = rlp.decode(self.db.get(newhash)) + childnode = rlp.decode(self.__lookup(newhash)) if len(childnode) == 2: newkey = k2 + bin_to_hexarraykey(childnode[0]) newnode = [ hexarraykey_to_bin(newkey), childnode[1] ] @@ -144,7 +151,7 @@ class Trie(): if onlynode == 16: newnode2 = [ hexarraykey_to_bin([16]), newnode[onlynode] ] elif onlynode >= 0: - childnode = rlp.decode(self.db.get(newnode[onlynode])) + childnode = rlp.decode(self.__lookup(newnode[onlynode])) if not childnode: raise Exception("?????") if len(childnode) == 17: @@ -158,7 +165,7 @@ class Trie(): def __get_size(self,node): if not node: return 0 - curnode = self.db.get(node) + curnode = self.__lookup(node) if not curnode: raise Exception("node not found in database") if len(curnode) == 2: @@ -174,7 +181,7 @@ class Trie(): def __to_dict(self,node): if not node: return {} - curnode = rlp.decode(self.db.get(node)) + curnode = rlp.decode(self.__lookup(node)) if not curnode: raise Exception("node not found in database") if len(curnode) == 2: