aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/geth/blocktest.go2
-rw-r--r--core/block_processor.go6
-rw-r--r--core/execution.go17
-rw-r--r--core/genesis.go2
-rw-r--r--core/state/statedb.go68
-rw-r--r--core/state_transition.go9
-rw-r--r--core/vm/vm.go3
-rw-r--r--tests/blocktest.go13
8 files changed, 77 insertions, 43 deletions
diff --git a/cmd/geth/blocktest.go b/cmd/geth/blocktest.go
index d9cdfa83f..f0b6bb1a2 100644
--- a/cmd/geth/blocktest.go
+++ b/cmd/geth/blocktest.go
@@ -60,7 +60,7 @@ func runblocktest(ctx *cli.Context) {
// insert the test blocks, which will execute all transactions
chain := ethereum.ChainManager()
if err := chain.InsertChain(test.Blocks); err != nil {
- utils.Fatalf("Block Test load error: %v", err)
+ utils.Fatalf("Block Test load error: %v %T", err, err)
} else {
fmt.Println("Block Test chain loaded")
}
diff --git a/core/block_processor.go b/core/block_processor.go
index e970ad06e..8fbf760af 100644
--- a/core/block_processor.go
+++ b/core/block_processor.go
@@ -326,8 +326,12 @@ func (sm *BlockProcessor) AccumulateRewards(statedb *state.StateDB, block, paren
return ValidationError(fmt.Sprintf("%v", err))
}
+ num := new(big.Int).Add(big.NewInt(8), uncle.Number)
+ num.Sub(num, block.Number())
+
r := new(big.Int)
- r.Mul(BlockReward, big.NewInt(15)).Div(r, big.NewInt(16))
+ r.Mul(BlockReward, num)
+ r.Div(r, big.NewInt(8))
statedb.AddBalance(uncle.Coinbase, r)
diff --git a/core/execution.go b/core/execution.go
index 24e085e6d..93fb03ecc 100644
--- a/core/execution.go
+++ b/core/execution.go
@@ -50,16 +50,29 @@ func (self *Execution) exec(contextAddr *common.Address, code []byte, caller vm.
}
vsnapshot := env.State().Copy()
+ var createAccount bool
if self.address == nil {
// Generate a new address
nonce := env.State().GetNonce(caller.Address())
- addr := crypto.CreateAddress(caller.Address(), nonce)
env.State().SetNonce(caller.Address(), nonce+1)
+
+ addr := crypto.CreateAddress(caller.Address(), nonce)
+
self.address = &addr
+ createAccount = true
}
snapshot := env.State().Copy()
- from, to := env.State().GetStateObject(caller.Address()), env.State().GetOrNewStateObject(*self.address)
+ var (
+ from = env.State().GetStateObject(caller.Address())
+ to *state.StateObject
+ )
+ if createAccount {
+ to = env.State().CreateAccount(*self.address)
+ } else {
+ to = env.State().GetOrNewStateObject(*self.address)
+ }
+
err = env.Transfer(from, to, self.value)
if err != nil {
env.State().Set(vsnapshot)
diff --git a/core/genesis.go b/core/genesis.go
index 716298231..7958157a4 100644
--- a/core/genesis.go
+++ b/core/genesis.go
@@ -47,7 +47,7 @@ func GenesisBlock(db common.Database) *types.Block {
statedb := state.New(genesis.Root(), db)
for addr, account := range accounts {
codedAddr := common.Hex2Bytes(addr)
- accountState := statedb.GetAccount(common.BytesToAddress(codedAddr))
+ accountState := statedb.CreateAccount(common.BytesToAddress(codedAddr))
accountState.SetBalance(common.Big(account.Balance))
accountState.SetCode(common.FromHex(account.Code))
statedb.UpdateStateObject(accountState)
diff --git a/core/state/statedb.go b/core/state/statedb.go
index 6fcd39dbc..2dc8239ef 100644
--- a/core/state/statedb.go
+++ b/core/state/statedb.go
@@ -57,6 +57,10 @@ func (self *StateDB) Refund(address common.Address, gas *big.Int) {
self.refund[addr].Add(self.refund[addr], gas)
}
+/*
+ * GETTERS
+ */
+
// Retrieve the balance from the given address or 0 if object not found
func (self *StateDB) GetBalance(addr common.Address) *big.Int {
stateObject := self.GetStateObject(addr)
@@ -67,13 +71,6 @@ func (self *StateDB) GetBalance(addr common.Address) *big.Int {
return common.Big0
}
-func (self *StateDB) AddBalance(addr common.Address, amount *big.Int) {
- stateObject := self.GetStateObject(addr)
- if stateObject != nil {
- stateObject.AddBalance(amount)
- }
-}
-
func (self *StateDB) GetNonce(addr common.Address) uint64 {
stateObject := self.GetStateObject(addr)
if stateObject != nil {
@@ -101,22 +98,41 @@ func (self *StateDB) GetState(a common.Address, b common.Hash) []byte {
return nil
}
-func (self *StateDB) SetNonce(addr common.Address, nonce uint64) {
+func (self *StateDB) IsDeleted(addr common.Address) bool {
stateObject := self.GetStateObject(addr)
if stateObject != nil {
+ return stateObject.remove
+ }
+ return false
+}
+
+/*
+ * SETTERS
+ */
+
+func (self *StateDB) AddBalance(addr common.Address, amount *big.Int) {
+ stateObject := self.GetOrNewStateObject(addr)
+ if stateObject != nil {
+ stateObject.AddBalance(amount)
+ }
+}
+
+func (self *StateDB) SetNonce(addr common.Address, nonce uint64) {
+ stateObject := self.GetOrNewStateObject(addr)
+ if stateObject != nil {
stateObject.SetNonce(nonce)
}
}
func (self *StateDB) SetCode(addr common.Address, code []byte) {
- stateObject := self.GetStateObject(addr)
+ stateObject := self.GetOrNewStateObject(addr)
if stateObject != nil {
stateObject.SetCode(code)
}
}
func (self *StateDB) SetState(addr common.Address, key common.Hash, value interface{}) {
- stateObject := self.GetStateObject(addr)
+ stateObject := self.GetOrNewStateObject(addr)
if stateObject != nil {
stateObject.SetState(key, common.NewValue(value))
}
@@ -134,14 +150,6 @@ func (self *StateDB) Delete(addr common.Address) bool {
return false
}
-func (self *StateDB) IsDeleted(addr common.Address) bool {
- stateObject := self.GetStateObject(addr)
- if stateObject != nil {
- return stateObject.remove
- }
- return false
-}
-
//
// Setting, updating & deleting state object methods
//
@@ -194,16 +202,14 @@ func (self *StateDB) SetStateObject(object *StateObject) {
func (self *StateDB) GetOrNewStateObject(addr common.Address) *StateObject {
stateObject := self.GetStateObject(addr)
if stateObject == nil {
- stateObject = self.NewStateObject(addr)
+ stateObject = self.CreateAccount(addr)
}
return stateObject
}
-// Create a state object whether it exist in the trie or not
-func (self *StateDB) NewStateObject(addr common.Address) *StateObject {
- //addr = common.Address(addr)
-
+// NewStateObject create a state object whether it exist in the trie or not
+func (self *StateDB) newStateObject(addr common.Address) *StateObject {
statelogger.Debugf("(+) %x\n", addr)
stateObject := NewStateObject(addr, self.db)
@@ -212,9 +218,19 @@ func (self *StateDB) NewStateObject(addr common.Address) *StateObject {
return stateObject
}
-// Deprecated
-func (self *StateDB) GetAccount(addr common.Address) *StateObject {
- return self.GetOrNewStateObject(addr)
+// Creates creates a new state object and takes ownership. This is different from "NewStateObject"
+func (self *StateDB) CreateAccount(addr common.Address) *StateObject {
+ // Get previous (if any)
+ so := self.GetStateObject(addr)
+ // Create a new one
+ newSo := self.newStateObject(addr)
+
+ // If it existed set the balance to the new account
+ if so != nil {
+ newSo.balance = so.balance
+ }
+
+ return newSo
}
//
diff --git a/core/state_transition.go b/core/state_transition.go
index 10a49f829..7616686db 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -183,15 +183,16 @@ func (self *StateTransition) transitionState() (ret []byte, usedGas *big.Int, er
}
// Pay data gas
- var dgas int64
+ dgas := new(big.Int)
for _, byt := range self.data {
if byt != 0 {
- dgas += vm.GasTxDataNonzeroByte.Int64()
+ dgas.Add(dgas, vm.GasTxDataNonzeroByte)
} else {
- dgas += vm.GasTxDataZeroByte.Int64()
+ dgas.Add(dgas, vm.GasTxDataZeroByte)
}
}
- if err = self.UseGas(big.NewInt(dgas)); err != nil {
+
+ if err = self.UseGas(dgas); err != nil {
return nil, nil, InvalidTxError(err)
}
diff --git a/core/vm/vm.go b/core/vm/vm.go
index 6c3dd240a..59c64e8a3 100644
--- a/core/vm/vm.go
+++ b/core/vm/vm.go
@@ -857,7 +857,8 @@ func (self *Vm) calculateGasAndSize(context *Context, caller ContextRef, op OpCo
quadCoef = new(big.Int).Div(pow, GasQuadCoeffDenom)
newTotalFee := new(big.Int).Add(linCoef, quadCoef)
- gas.Add(gas, new(big.Int).Sub(newTotalFee, oldTotalFee))
+ fee := new(big.Int).Sub(newTotalFee, oldTotalFee)
+ gas.Add(gas, fee)
}
}
diff --git a/tests/blocktest.go b/tests/blocktest.go
index d813ebeec..fc62eda58 100644
--- a/tests/blocktest.go
+++ b/tests/blocktest.go
@@ -4,7 +4,6 @@ import (
"bytes"
"encoding/hex"
"encoding/json"
- "errors"
"fmt"
"io/ioutil"
"math/big"
@@ -69,7 +68,7 @@ type btBlock struct {
BlockHeader *btHeader
Rlp string
Transactions []btTransaction
- UncleHeaders []string
+ UncleHeaders []*btHeader
}
type BlockTest struct {
@@ -106,13 +105,13 @@ func (t *BlockTest) InsertPreState(db common.Database) (*state.StateDB, error) {
balance, _ := new(big.Int).SetString(acct.Balance, 0)
nonce, _ := strconv.ParseUint(acct.Nonce, 16, 64)
- obj := statedb.NewStateObject(common.HexToAddress(addrString))
+ obj := statedb.CreateAccount(common.HexToAddress(addrString))
obj.SetCode(code)
obj.SetBalance(balance)
obj.SetNonce(nonce)
- // for k, v := range acct.Storage {
- // obj.SetState(k, v)
- // }
+ for k, v := range acct.Storage {
+ statedb.SetState(common.HexToAddress(addrString), common.HexToHash(k), common.FromHex(v))
+ }
}
// sync objects to trie
statedb.Update(nil)
@@ -120,7 +119,7 @@ func (t *BlockTest) InsertPreState(db common.Database) (*state.StateDB, error) {
statedb.Sync()
if !bytes.Equal(t.Genesis.Root().Bytes(), statedb.Root().Bytes()) {
- return nil, errors.New("computed state root does not match genesis block")
+ return nil, fmt.Errorf("computed state root does not match genesis block %x %x", t.Genesis.Root().Bytes()[:4], statedb.Root().Bytes()[:4])
}
return statedb, nil
}