Updated trie format and stack language

This commit is contained in:
Vitalik Buterin 2014-01-07 12:40:49 -05:00
parent 9d47cacc47
commit f1208195f4
3 changed files with 47 additions and 37 deletions

View File

@ -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 = ''

View File

@ -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

29
trie.py
View File

@ -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: