Documented methods & removed old manifest
This commit is contained in:
parent
558c67d392
commit
3f6baa45a7
1
cmd/mist/assets/examples/coin.js
Normal file
1
cmd/mist/assets/examples/coin.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
var contract = web3.eth.contractFromAbi([{"constant":false,"inputs":[{"name":"_h","type":"hash256"}],"name":"confirm","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"execute","outputs":[{"name":"_r","type":"hash256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"}],"name":"kill","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"}],"name":"changeOwner","outputs":[],"type":"function"},{"inputs":[{"indexed":false,"name":"value","type":"uint256"}],"name":"CashIn","type":"event"},{"inputs":[{"indexed":true,"name":"out","type":"string32"},{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"to","type":"address"}],"name":"SingleTransact","type":"event"},{"inputs":[{"indexed":true,"name":"out","type":"string32"},{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"operation","type":"hash256"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"to","type":"address"}],"name":"MultiTransact","type":"event"}]);
|
@ -143,6 +143,9 @@ func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, state
|
|||||||
return receipts, handled, unhandled, erroneous, err
|
return receipts, handled, unhandled, erroneous, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Process block will attempt to process the given block's transactions and applies them
|
||||||
|
// on top of the block's parent state (given it exists) and will return wether it was
|
||||||
|
// successful or not.
|
||||||
func (sm *BlockProcessor) Process(block *types.Block) (td *big.Int, err error) {
|
func (sm *BlockProcessor) Process(block *types.Block) (td *big.Int, err error) {
|
||||||
// Processing a blocks may never happen simultaneously
|
// Processing a blocks may never happen simultaneously
|
||||||
sm.mutex.Lock()
|
sm.mutex.Lock()
|
||||||
@ -158,14 +161,14 @@ func (sm *BlockProcessor) Process(block *types.Block) (td *big.Int, err error) {
|
|||||||
}
|
}
|
||||||
parent := sm.bc.GetBlock(header.ParentHash)
|
parent := sm.bc.GetBlock(header.ParentHash)
|
||||||
|
|
||||||
return sm.ProcessWithParent(block, parent)
|
return sm.processWithParent(block, parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *BlockProcessor) ProcessWithParent(block, parent *types.Block) (td *big.Int, err error) {
|
func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (td *big.Int, err error) {
|
||||||
sm.lastAttemptedBlock = block
|
sm.lastAttemptedBlock = block
|
||||||
|
|
||||||
|
// Create a new state based on the parent's root (e.g., create copy)
|
||||||
state := state.New(parent.Root(), sm.db)
|
state := state.New(parent.Root(), sm.db)
|
||||||
//state := state.New(parent.Trie().Copy())
|
|
||||||
|
|
||||||
// Block validation
|
// Block validation
|
||||||
if err = sm.ValidateBlock(block, parent); err != nil {
|
if err = sm.ValidateBlock(block, parent); err != nil {
|
||||||
@ -179,18 +182,23 @@ func (sm *BlockProcessor) ProcessWithParent(block, parent *types.Block) (td *big
|
|||||||
|
|
||||||
header := block.Header()
|
header := block.Header()
|
||||||
|
|
||||||
|
// Validate the received block's bloom with the one derived from the generated receipts.
|
||||||
|
// For valid blocks this should always validate to true.
|
||||||
rbloom := types.CreateBloom(receipts)
|
rbloom := types.CreateBloom(receipts)
|
||||||
if bytes.Compare(rbloom, header.Bloom) != 0 {
|
if bytes.Compare(rbloom, header.Bloom) != 0 {
|
||||||
err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom)
|
err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The transactions Trie's root (R = (Tr [[H1, T1], [H2, T2], ... [Hn, Tn]]))
|
||||||
|
// can be used by light clients to make sure they've received the correct Txs
|
||||||
txSha := types.DeriveSha(block.Transactions())
|
txSha := types.DeriveSha(block.Transactions())
|
||||||
if bytes.Compare(txSha, header.TxHash) != 0 {
|
if bytes.Compare(txSha, header.TxHash) != 0 {
|
||||||
err = fmt.Errorf("validating transaction root. received=%x got=%x", header.TxHash, txSha)
|
err = fmt.Errorf("validating transaction root. received=%x got=%x", header.TxHash, txSha)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tre receipt Trie's root (R = (Tr [[H1, R1], ... [Hn, R1]]))
|
||||||
receiptSha := types.DeriveSha(receipts)
|
receiptSha := types.DeriveSha(receipts)
|
||||||
if bytes.Compare(receiptSha, header.ReceiptHash) != 0 {
|
if bytes.Compare(receiptSha, header.ReceiptHash) != 0 {
|
||||||
fmt.Println("receipts", receipts)
|
fmt.Println("receipts", receipts)
|
||||||
@ -198,12 +206,14 @@ func (sm *BlockProcessor) ProcessWithParent(block, parent *types.Block) (td *big
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Accumulate static rewards; block reward, uncle's and uncle inclusion.
|
||||||
if err = sm.AccumulateRewards(state, block, parent); err != nil {
|
if err = sm.AccumulateRewards(state, block, parent); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Commit state objects/accounts to a temporary trie (does not save)
|
||||||
|
// used to calculate the state root.
|
||||||
state.Update(ethutil.Big0)
|
state.Update(ethutil.Big0)
|
||||||
|
|
||||||
if !bytes.Equal(header.Root, state.Root()) {
|
if !bytes.Equal(header.Root, state.Root()) {
|
||||||
err = fmt.Errorf("invalid merkle root. received=%x got=%x", header.Root, state.Root())
|
err = fmt.Errorf("invalid merkle root. received=%x got=%x", header.Root, state.Root())
|
||||||
return
|
return
|
||||||
@ -213,10 +223,6 @@ func (sm *BlockProcessor) ProcessWithParent(block, parent *types.Block) (td *big
|
|||||||
td = CalculateTD(block, parent)
|
td = CalculateTD(block, parent)
|
||||||
// Sync the current block's state to the database
|
// Sync the current block's state to the database
|
||||||
state.Sync()
|
state.Sync()
|
||||||
// Set the block hashes for the current messages
|
|
||||||
state.Manifest().SetHash(block.Hash())
|
|
||||||
// Reset the manifest XXX We need this?
|
|
||||||
state.Manifest().Reset()
|
|
||||||
// Remove transactions from the pool
|
// Remove transactions from the pool
|
||||||
sm.txpool.RemoveSet(block.Transactions())
|
sm.txpool.RemoveSet(block.Transactions())
|
||||||
|
|
||||||
@ -296,27 +302,6 @@ func (sm *BlockProcessor) AccumulateRewards(statedb *state.StateDB, block, paren
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *BlockProcessor) GetMessages(block *types.Block) (messages []*state.Message, err error) {
|
|
||||||
if !sm.bc.HasBlock(block.Header().ParentHash) {
|
|
||||||
return nil, ParentError(block.Header().ParentHash)
|
|
||||||
}
|
|
||||||
|
|
||||||
sm.lastAttemptedBlock = block
|
|
||||||
|
|
||||||
var (
|
|
||||||
parent = sm.bc.GetBlock(block.Header().ParentHash)
|
|
||||||
//state = state.New(parent.Trie().Copy())
|
|
||||||
state = state.New(parent.Root(), sm.db)
|
|
||||||
)
|
|
||||||
|
|
||||||
defer state.Reset()
|
|
||||||
|
|
||||||
sm.TransitionState(state, parent, block)
|
|
||||||
sm.AccumulateRewards(state, block, parent)
|
|
||||||
|
|
||||||
return state.Manifest().Messages, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err error) {
|
func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err error) {
|
||||||
if !sm.bc.HasBlock(block.Header().ParentHash) {
|
if !sm.bc.HasBlock(block.Header().ParentHash) {
|
||||||
return nil, ParentError(block.Header().ParentHash)
|
return nil, ParentError(block.Header().ParentHash)
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
package state
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"math/big"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Object manifest
|
|
||||||
//
|
|
||||||
// The object manifest is used to keep changes to the state so we can keep track of the changes
|
|
||||||
// that occurred during a state transitioning phase.
|
|
||||||
type Manifest struct {
|
|
||||||
Messages Messages
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewManifest() *Manifest {
|
|
||||||
m := &Manifest{}
|
|
||||||
m.Reset()
|
|
||||||
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Manifest) Reset() {
|
|
||||||
m.Messages = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Manifest) AddMessage(msg *Message) *Message {
|
|
||||||
self.Messages = append(self.Messages, msg)
|
|
||||||
|
|
||||||
return msg
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Manifest) SetHash(hash []byte) {
|
|
||||||
for _, message := range self.Messages {
|
|
||||||
message.Block = hash
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Messages []*Message
|
|
||||||
type Message struct {
|
|
||||||
To, From []byte
|
|
||||||
Input []byte
|
|
||||||
Output []byte
|
|
||||||
Path int
|
|
||||||
Origin []byte
|
|
||||||
Timestamp int64
|
|
||||||
Coinbase []byte
|
|
||||||
Block []byte
|
|
||||||
Number *big.Int
|
|
||||||
Value *big.Int
|
|
||||||
|
|
||||||
ChangedAddresses [][]byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Message) AddStorageChange(addr []byte) {
|
|
||||||
self.ChangedAddresses = append(self.ChangedAddresses, addr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Message) String() string {
|
|
||||||
return fmt.Sprintf("Message{to: %x from: %x input: %x output: %x origin: %x coinbase: %x block: %x number: %v timestamp: %d path: %d value: %v", self.To, self.From, self.Input, self.Output, self.Origin, self.Coinbase, self.Block, self.Number, self.Timestamp, self.Path, self.Value)
|
|
||||||
}
|
|
@ -22,8 +22,6 @@ type StateDB struct {
|
|||||||
|
|
||||||
stateObjects map[string]*StateObject
|
stateObjects map[string]*StateObject
|
||||||
|
|
||||||
manifest *Manifest
|
|
||||||
|
|
||||||
refund map[string]*big.Int
|
refund map[string]*big.Int
|
||||||
|
|
||||||
logs Logs
|
logs Logs
|
||||||
@ -32,7 +30,7 @@ type StateDB struct {
|
|||||||
// Create a new state from a given trie
|
// Create a new state from a given trie
|
||||||
func New(root []byte, db ethutil.Database) *StateDB {
|
func New(root []byte, db ethutil.Database) *StateDB {
|
||||||
trie := trie.New(ethutil.CopyBytes(root), db)
|
trie := trie.New(ethutil.CopyBytes(root), db)
|
||||||
return &StateDB{db: db, trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string]*big.Int)}
|
return &StateDB{db: db, trie: trie, stateObjects: make(map[string]*StateObject), refund: make(map[string]*big.Int)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateDB) EmptyLogs() {
|
func (self *StateDB) EmptyLogs() {
|
||||||
@ -47,6 +45,13 @@ func (self *StateDB) Logs() Logs {
|
|||||||
return self.logs
|
return self.logs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *StateDB) Refund(addr []byte, gas *big.Int) {
|
||||||
|
if self.refund[string(addr)] == nil {
|
||||||
|
self.refund[string(addr)] = new(big.Int)
|
||||||
|
}
|
||||||
|
self.refund[string(addr)].Add(self.refund[string(addr)], gas)
|
||||||
|
}
|
||||||
|
|
||||||
// Retrieve the balance from the given address or 0 if object not found
|
// Retrieve the balance from the given address or 0 if object not found
|
||||||
func (self *StateDB) GetBalance(addr []byte) *big.Int {
|
func (self *StateDB) GetBalance(addr []byte) *big.Int {
|
||||||
stateObject := self.GetStateObject(addr)
|
stateObject := self.GetStateObject(addr)
|
||||||
@ -57,13 +62,6 @@ func (self *StateDB) GetBalance(addr []byte) *big.Int {
|
|||||||
return ethutil.Big0
|
return ethutil.Big0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateDB) Refund(addr []byte, gas *big.Int) {
|
|
||||||
if self.refund[string(addr)] == nil {
|
|
||||||
self.refund[string(addr)] = new(big.Int)
|
|
||||||
}
|
|
||||||
self.refund[string(addr)].Add(self.refund[string(addr)], gas)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *StateDB) AddBalance(addr []byte, amount *big.Int) {
|
func (self *StateDB) AddBalance(addr []byte, amount *big.Int) {
|
||||||
stateObject := self.GetStateObject(addr)
|
stateObject := self.GetStateObject(addr)
|
||||||
if stateObject != nil {
|
if stateObject != nil {
|
||||||
@ -103,6 +101,7 @@ func (self *StateDB) SetCode(addr, code []byte) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO vars
|
||||||
func (self *StateDB) GetState(a, b []byte) []byte {
|
func (self *StateDB) GetState(a, b []byte) []byte {
|
||||||
stateObject := self.GetStateObject(a)
|
stateObject := self.GetStateObject(a)
|
||||||
if stateObject != nil {
|
if stateObject != nil {
|
||||||
@ -212,25 +211,21 @@ func (s *StateDB) Cmp(other *StateDB) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateDB) Copy() *StateDB {
|
func (self *StateDB) Copy() *StateDB {
|
||||||
if self.trie != nil {
|
state := New(nil, self.db)
|
||||||
state := New(nil, self.db)
|
state.trie = self.trie.Copy()
|
||||||
state.trie = self.trie.Copy()
|
for k, stateObject := range self.stateObjects {
|
||||||
for k, stateObject := range self.stateObjects {
|
state.stateObjects[k] = stateObject.Copy()
|
||||||
state.stateObjects[k] = stateObject.Copy()
|
|
||||||
}
|
|
||||||
|
|
||||||
for addr, refund := range self.refund {
|
|
||||||
state.refund[addr] = new(big.Int).Set(refund)
|
|
||||||
}
|
|
||||||
|
|
||||||
logs := make(Logs, len(self.logs))
|
|
||||||
copy(logs, self.logs)
|
|
||||||
state.logs = logs
|
|
||||||
|
|
||||||
return state
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
for addr, refund := range self.refund {
|
||||||
|
state.refund[addr] = new(big.Int).Set(refund)
|
||||||
|
}
|
||||||
|
|
||||||
|
logs := make(Logs, len(self.logs))
|
||||||
|
copy(logs, self.logs)
|
||||||
|
state.logs = logs
|
||||||
|
|
||||||
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateDB) Set(state *StateDB) {
|
func (self *StateDB) Set(state *StateDB) {
|
||||||
@ -301,10 +296,6 @@ func (self *StateDB) Update(gasUsed *big.Int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateDB) Manifest() *Manifest {
|
|
||||||
return self.manifest
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debug stuff
|
// Debug stuff
|
||||||
func (self *StateDB) CreateOutputForDiff() {
|
func (self *StateDB) CreateOutputForDiff() {
|
||||||
for _, stateObject := range self.stateObjects {
|
for _, stateObject := range self.stateObjects {
|
||||||
|
11
vm/vm.go
11
vm/vm.go
@ -38,13 +38,6 @@ func New(env Environment) *Vm {
|
|||||||
func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) {
|
func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) {
|
||||||
self.env.SetDepth(self.env.Depth() + 1)
|
self.env.SetDepth(self.env.Depth() + 1)
|
||||||
|
|
||||||
msg := self.env.State().Manifest().AddMessage(&state.Message{
|
|
||||||
To: me.Address(), From: caller.Address(),
|
|
||||||
Input: callData,
|
|
||||||
Origin: self.env.Origin(),
|
|
||||||
Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(),
|
|
||||||
Value: value,
|
|
||||||
})
|
|
||||||
context := NewContext(caller, me, code, gas, price)
|
context := NewContext(caller, me, code, gas, price)
|
||||||
|
|
||||||
vmlogger.Debugf("(%d) (%x) %x (code=%d) gas: %v (d) %x\n", self.env.Depth(), caller.Address()[:4], context.Address(), len(code), context.Gas, callData)
|
vmlogger.Debugf("(%d) (%x) %x (code=%d) gas: %v (d) %x\n", self.env.Depth(), caller.Address()[:4], context.Address(), len(code), context.Gas, callData)
|
||||||
@ -618,8 +611,6 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
|
|||||||
val, loc := stack.Popn()
|
val, loc := stack.Popn()
|
||||||
statedb.SetState(context.Address(), loc.Bytes(), val)
|
statedb.SetState(context.Address(), loc.Bytes(), val)
|
||||||
|
|
||||||
msg.AddStorageChange(loc.Bytes())
|
|
||||||
|
|
||||||
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
|
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
|
||||||
case JUMP:
|
case JUMP:
|
||||||
jump(pc, stack.Pop())
|
jump(pc, stack.Pop())
|
||||||
@ -670,7 +661,6 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
|
|||||||
dataGas.Mul(dataGas, GasCreateByte)
|
dataGas.Mul(dataGas, GasCreateByte)
|
||||||
if context.UseGas(dataGas) {
|
if context.UseGas(dataGas) {
|
||||||
ref.SetCode(ret)
|
ref.SetCode(ret)
|
||||||
msg.Output = ret
|
|
||||||
}
|
}
|
||||||
addr = ref.Address()
|
addr = ref.Address()
|
||||||
|
|
||||||
@ -713,7 +703,6 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
|
|||||||
vmlogger.Debugln(err)
|
vmlogger.Debugln(err)
|
||||||
} else {
|
} else {
|
||||||
stack.Push(ethutil.BigTrue)
|
stack.Push(ethutil.BigTrue)
|
||||||
msg.Output = ret
|
|
||||||
|
|
||||||
mem.Set(retOffset.Uint64(), retSize.Uint64(), ret)
|
mem.Set(retOffset.Uint64(), retSize.Uint64(), ret)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user