Merge remote-tracking branch 'upstream/develop' into kademlia

This commit is contained in:
zelig 2015-01-07 18:19:48 +00:00
commit 67ccc4f2f6
44 changed files with 847 additions and 559 deletions

12
.mailmap Normal file
View file

@ -0,0 +1,12 @@
Jeffrey Wilcke <jeffrey@ethereum.org>
Jeffrey Wilcke <jeffrey@ethereum.org> <geffobscura@gmail.com>
Jeffrey Wilcke <jeffrey@ethereum.org> <obscuren@obscura.com>
Jeffrey Wilcke <jeffrey@ethereum.org> <obscuren@users.noreply.github.com>
Viktor Trón <viktor.tron@gmail.com>
Joseph Goulden <joegoulden@gmail.com>
Nick Savers <nicksavers@gmail.com>
Maran Hidskes <maran.hidskes@gmail.com>

View file

@ -64,6 +64,7 @@ var (
ImportChain string ImportChain string
SHH bool SHH bool
Dial bool Dial bool
PrintVersion bool
) )
// flags specific to cli client // flags specific to cli client
@ -120,6 +121,7 @@ func Init() {
flag.BoolVar(&StartMining, "mine", false, "start dagger mining") flag.BoolVar(&StartMining, "mine", false, "start dagger mining")
flag.BoolVar(&StartJsConsole, "js", false, "launches javascript console") flag.BoolVar(&StartJsConsole, "js", false, "launches javascript console")
flag.BoolVar(&PrintVersion, "version", false, "prints version number")
flag.Parse() flag.Parse()

View file

@ -31,6 +31,7 @@ import (
"github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/state"
) )
const ( const (
@ -52,6 +53,11 @@ func main() {
// precedence: code-internal flag default < config file < environment variables < command line // precedence: code-internal flag default < config file < environment variables < command line
Init() // parsing command line Init() // parsing command line
if PrintVersion {
printVersion()
return
}
utils.InitConfig(VmType, ConfigFile, Datadir, "ETH") utils.InitConfig(VmType, ConfigFile, Datadir, "ETH")
ethereum, err := eth.New(&eth.Config{ ethereum, err := eth.New(&eth.Config{
@ -98,7 +104,8 @@ func main() {
} }
// Leave the Println. This needs clean output for piping // Leave the Println. This needs clean output for piping
fmt.Printf("%s\n", block.State().Dump()) statedb := state.New(block.Root(), ethereum.Db())
fmt.Printf("%s\n", statedb.Dump())
fmt.Println(block) fmt.Println(block)
@ -137,3 +144,13 @@ func main() {
// this blocks the thread // this blocks the thread
ethereum.WaitForShutdown() ethereum.WaitForShutdown()
} }
func printVersion() {
fmt.Printf(`%v %v
PV=%d
GOOS=%s
GO=%s
GOPATH=%s
GOROOT=%s
`, ClientIdentifier, Version, eth.ProtocolVersion, runtime.GOOS, runtime.Version(), os.Getenv("GOPATH"), runtime.GOROOT())
}

View file

@ -24,11 +24,12 @@ package main
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"io"
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
"strings"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/tests/helper" "github.com/ethereum/go-ethereum/tests/helper"
@ -41,8 +42,8 @@ type Account struct {
Storage map[string]string Storage map[string]string
} }
func StateObjectFromAccount(addr string, account Account) *state.StateObject { func StateObjectFromAccount(db ethutil.Database, addr string, account Account) *state.StateObject {
obj := state.NewStateObject(ethutil.Hex2Bytes(addr)) obj := state.NewStateObject(ethutil.Hex2Bytes(addr), db)
obj.SetBalance(ethutil.Big(account.Balance)) obj.SetBalance(ethutil.Big(account.Balance))
if ethutil.IsHex(account.Code) { if ethutil.IsHex(account.Code) {
@ -64,19 +65,20 @@ type VmTest struct {
Pre map[string]Account Pre map[string]Account
} }
func RunVmTest(js string) (failed int) { func RunVmTest(r io.Reader) (failed int) {
tests := make(map[string]VmTest) tests := make(map[string]VmTest)
data, _ := ioutil.ReadAll(strings.NewReader(js)) data, _ := ioutil.ReadAll(r)
err := json.Unmarshal(data, &tests) err := json.Unmarshal(data, &tests)
if err != nil { if err != nil {
log.Fatalln(err) log.Fatalln(err)
} }
for name, test := range tests { for name, test := range tests {
state := state.New(helper.NewTrie()) db, _ := ethdb.NewMemDatabase()
state := state.New(nil, db)
for addr, account := range test.Pre { for addr, account := range test.Pre {
obj := StateObjectFromAccount(addr, account) obj := StateObjectFromAccount(db, addr, account)
state.SetStateObject(obj) state.SetStateObject(obj)
} }
@ -123,9 +125,6 @@ func RunVmTest(js string) (failed int) {
func main() { func main() {
helper.Logger.SetLogLevel(5) helper.Logger.SetLogLevel(5)
if len(os.Args) == 1 {
log.Fatalln("no json supplied")
}
os.Exit(RunVmTest(os.Args[1])) os.Exit(RunVmTest(os.Stdin))
} }

View file

@ -35,7 +35,6 @@ import (
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/ptrie"
"github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/vm" "github.com/ethereum/go-ethereum/vm"
) )
@ -63,7 +62,7 @@ func main() {
ethutil.ReadConfig("/tmp/evmtest", "/tmp/evm", "") ethutil.ReadConfig("/tmp/evmtest", "/tmp/evm", "")
db, _ := ethdb.NewMemDatabase() db, _ := ethdb.NewMemDatabase()
statedb := state.New(ptrie.New(nil, db)) statedb := state.New(nil, db)
sender := statedb.NewStateObject([]byte("sender")) sender := statedb.NewStateObject([]byte("sender"))
receiver := statedb.NewStateObject([]byte("receiver")) receiver := statedb.NewStateObject([]byte("receiver"))
//receiver.SetCode([]byte(*code)) //receiver.SetCode([]byte(*code))

View file

@ -29,6 +29,7 @@ import (
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/state"
) )
type plugin struct { type plugin struct {
@ -121,7 +122,7 @@ func (self *Gui) DumpState(hash, path string) {
return return
} }
stateDump = block.State().Dump() stateDump = state.New(block.Root(), self.eth.Db()).Dump()
} }
file, err := os.OpenFile(path[7:], os.O_CREATE|os.O_RDWR, os.ModePerm) file, err := os.OpenFile(path[7:], os.O_CREATE|os.O_RDWR, os.ModePerm)

View file

@ -117,18 +117,7 @@ func (gui *Gui) Start(assetPath string) {
context.SetVar("eth", gui.uiLib) context.SetVar("eth", gui.uiLib)
context.SetVar("shh", gui.whisper) context.SetVar("shh", gui.whisper)
// Load the main QML interface win, err := gui.showWallet(context)
data, _ := ethutil.Config.Db.Get([]byte("KeyRing"))
var win *qml.Window
var err error
var addlog = false
if len(data) == 0 {
win, err = gui.showKeyImport(context)
} else {
win, err = gui.showWallet(context)
addlog = true
}
if err != nil { if err != nil {
guilogger.Errorln("asset not found: you can set an alternative asset path on the command line using option 'asset_path'", err) guilogger.Errorln("asset not found: you can set an alternative asset path on the command line using option 'asset_path'", err)
@ -139,9 +128,7 @@ func (gui *Gui) Start(assetPath string) {
win.Show() win.Show()
// only add the gui guilogger after window is shown otherwise slider wont be shown // only add the gui guilogger after window is shown otherwise slider wont be shown
if addlog { logger.AddLogSystem(gui)
logger.AddLogSystem(gui)
}
win.Wait() win.Wait()
// need to silence gui guilogger after window closed otherwise logsystem hangs (but do not save loglevel) // need to silence gui guilogger after window closed otherwise logsystem hangs (but do not save loglevel)
@ -275,7 +262,7 @@ func (gui *Gui) insertTransaction(window string, tx *types.Transaction) {
} }
var ( var (
ptx = xeth.NewJSTx(tx, gui.xeth.World().State()) ptx = xeth.NewJSTx(tx)
send = nameReg.Storage(tx.From()) send = nameReg.Storage(tx.From())
rec = nameReg.Storage(tx.To()) rec = nameReg.Storage(tx.To())
s, r string s, r string

View file

@ -39,6 +39,7 @@ import (
"github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/miner"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/xeth" "github.com/ethereum/go-ethereum/xeth"
) )
@ -259,7 +260,8 @@ func BlockDo(ethereum *eth.Ethereum, hash []byte) error {
parent := ethereum.ChainManager().GetBlock(block.ParentHash()) parent := ethereum.ChainManager().GetBlock(block.ParentHash())
_, err := ethereum.BlockProcessor().TransitionState(parent.State(), parent, block) statedb := state.New(parent.Root(), ethereum.Db())
_, err := ethereum.BlockProcessor().TransitionState(statedb, parent, block)
if err != nil { if err != nil {
return err return err
} }

View file

@ -36,6 +36,7 @@ type EthManager interface {
} }
type BlockProcessor struct { type BlockProcessor struct {
db ethutil.Database
// Mutex for locking the block processor. Blocks can only be handled one at a time // Mutex for locking the block processor. Blocks can only be handled one at a time
mutex sync.Mutex mutex sync.Mutex
// Canonical block chain // Canonical block chain
@ -57,8 +58,9 @@ type BlockProcessor struct {
eventMux *event.TypeMux eventMux *event.TypeMux
} }
func NewBlockProcessor(txpool *TxPool, chainManager *ChainManager, eventMux *event.TypeMux) *BlockProcessor { func NewBlockProcessor(db ethutil.Database, txpool *TxPool, chainManager *ChainManager, eventMux *event.TypeMux) *BlockProcessor {
sm := &BlockProcessor{ sm := &BlockProcessor{
db: db,
mem: make(map[string]*big.Int), mem: make(map[string]*big.Int),
Pow: ezp.New(), Pow: ezp.New(),
bc: chainManager, bc: chainManager,
@ -170,7 +172,8 @@ func (sm *BlockProcessor) Process(block *types.Block) (td *big.Int, msgs state.M
func (sm *BlockProcessor) ProcessWithParent(block, parent *types.Block) (td *big.Int, messages state.Messages, err error) { func (sm *BlockProcessor) ProcessWithParent(block, parent *types.Block) (td *big.Int, messages state.Messages, err error) {
sm.lastAttemptedBlock = block sm.lastAttemptedBlock = block
state := state.New(parent.Trie().Copy()) 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 {
@ -264,6 +267,7 @@ func (sm *BlockProcessor) ValidateBlock(block, parent *types.Block) error {
expd := CalcDifficulty(block, parent) expd := CalcDifficulty(block, parent)
if expd.Cmp(block.Header().Difficulty) < 0 { if expd.Cmp(block.Header().Difficulty) < 0 {
fmt.Println("parent\n", parent)
return fmt.Errorf("Difficulty check failed for block %v, %v", block.Header().Difficulty, expd) return fmt.Errorf("Difficulty check failed for block %v, %v", block.Header().Difficulty, expd)
} }
@ -351,7 +355,8 @@ func (sm *BlockProcessor) GetMessages(block *types.Block) (messages []*state.Mes
var ( var (
parent = sm.bc.GetBlock(block.Header().ParentHash) parent = sm.bc.GetBlock(block.Header().ParentHash)
state = state.New(parent.Trie().Copy()) //state = state.New(parent.Trie().Copy())
state = state.New(parent.Root(), sm.db)
) )
defer state.Reset() defer state.Reset()

View file

@ -25,7 +25,7 @@ func CalcDifficulty(block, parent *types.Block) *big.Int {
bh, ph := block.Header(), parent.Header() bh, ph := block.Header(), parent.Header()
adjust := new(big.Int).Rsh(ph.Difficulty, 10) adjust := new(big.Int).Rsh(ph.Difficulty, 10)
if bh.Time >= ph.Time+5 { if bh.Time >= ph.Time+13 {
diff.Sub(ph.Difficulty, adjust) diff.Sub(ph.Difficulty, adjust)
} else { } else {
diff.Add(ph.Difficulty, adjust) diff.Add(ph.Difficulty, adjust)
@ -55,6 +55,7 @@ func CalcGasLimit(parent, block *types.Block) *big.Int {
type ChainManager struct { type ChainManager struct {
//eth EthManager //eth EthManager
db ethutil.Database
processor types.BlockProcessor processor types.BlockProcessor
eventMux *event.TypeMux eventMux *event.TypeMux
genesisBlock *types.Block genesisBlock *types.Block
@ -96,13 +97,9 @@ func (self *ChainManager) CurrentBlock() *types.Block {
return self.currentBlock return self.currentBlock
} }
func NewChainManager(mux *event.TypeMux) *ChainManager { func NewChainManager(db ethutil.Database, mux *event.TypeMux) *ChainManager {
bc := &ChainManager{} bc := &ChainManager{db: db, genesisBlock: GenesisBlock(db), eventMux: mux}
bc.genesisBlock = GenesisBlock()
bc.eventMux = mux
bc.setLastBlock() bc.setLastBlock()
bc.transState = bc.State().Copy() bc.transState = bc.State().Copy()
return bc return bc
@ -120,7 +117,7 @@ func (self *ChainManager) SetProcessor(proc types.BlockProcessor) {
} }
func (self *ChainManager) State() *state.StateDB { func (self *ChainManager) State() *state.StateDB {
return state.New(self.CurrentBlock().Trie()) return state.New(self.CurrentBlock().Root(), self.db)
} }
func (self *ChainManager) TransState() *state.StateDB { func (self *ChainManager) TransState() *state.StateDB {
@ -128,7 +125,7 @@ func (self *ChainManager) TransState() *state.StateDB {
} }
func (bc *ChainManager) setLastBlock() { func (bc *ChainManager) setLastBlock() {
data, _ := ethutil.Config.Db.Get([]byte("LastBlock")) data, _ := bc.db.Get([]byte("LastBlock"))
if len(data) != 0 { if len(data) != 0 {
var block types.Block var block types.Block
rlp.Decode(bytes.NewReader(data), &block) rlp.Decode(bytes.NewReader(data), &block)
@ -137,7 +134,7 @@ func (bc *ChainManager) setLastBlock() {
bc.lastBlockNumber = block.Header().Number.Uint64() bc.lastBlockNumber = block.Header().Number.Uint64()
// Set the last know difficulty (might be 0x0 as initial value, Genesis) // Set the last know difficulty (might be 0x0 as initial value, Genesis)
bc.td = ethutil.BigD(ethutil.Config.Db.LastKnownTD()) bc.td = ethutil.BigD(bc.db.LastKnownTD())
} else { } else {
bc.Reset() bc.Reset()
} }
@ -183,7 +180,7 @@ func (bc *ChainManager) Reset() {
defer bc.mu.Unlock() defer bc.mu.Unlock()
for block := bc.currentBlock; block != nil; block = bc.GetBlock(block.Header().ParentHash) { for block := bc.currentBlock; block != nil; block = bc.GetBlock(block.Header().ParentHash) {
ethutil.Config.Db.Delete(block.Hash()) bc.db.Delete(block.Hash())
} }
// Prepare the genesis block // Prepare the genesis block
@ -210,7 +207,7 @@ func (self *ChainManager) Export() []byte {
func (bc *ChainManager) insert(block *types.Block) { func (bc *ChainManager) insert(block *types.Block) {
encodedBlock := ethutil.Encode(block) encodedBlock := ethutil.Encode(block)
ethutil.Config.Db.Put([]byte("LastBlock"), encodedBlock) bc.db.Put([]byte("LastBlock"), encodedBlock)
bc.currentBlock = block bc.currentBlock = block
bc.lastBlockHash = block.Hash() bc.lastBlockHash = block.Hash()
} }
@ -219,7 +216,7 @@ func (bc *ChainManager) write(block *types.Block) {
bc.writeBlockInfo(block) bc.writeBlockInfo(block)
encodedBlock := ethutil.Encode(block) encodedBlock := ethutil.Encode(block)
ethutil.Config.Db.Put(block.Hash(), encodedBlock) bc.db.Put(block.Hash(), encodedBlock)
} }
// Accessors // Accessors
@ -229,7 +226,7 @@ func (bc *ChainManager) Genesis() *types.Block {
// Block fetching methods // Block fetching methods
func (bc *ChainManager) HasBlock(hash []byte) bool { func (bc *ChainManager) HasBlock(hash []byte) bool {
data, _ := ethutil.Config.Db.Get(hash) data, _ := bc.db.Get(hash)
return len(data) != 0 return len(data) != 0
} }
@ -254,7 +251,7 @@ func (self *ChainManager) GetBlockHashesFromHash(hash []byte, max uint64) (chain
} }
func (self *ChainManager) GetBlock(hash []byte) *types.Block { func (self *ChainManager) GetBlock(hash []byte) *types.Block {
data, _ := ethutil.Config.Db.Get(hash) data, _ := self.db.Get(hash)
if len(data) == 0 { if len(data) == 0 {
return nil return nil
} }
@ -286,7 +283,7 @@ func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block {
} }
func (bc *ChainManager) setTotalDifficulty(td *big.Int) { func (bc *ChainManager) setTotalDifficulty(td *big.Int) {
ethutil.Config.Db.Put([]byte("LTD"), td.Bytes()) bc.db.Put([]byte("LTD"), td.Bytes())
bc.td = td bc.td = td
} }
@ -348,7 +345,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
self.setTotalDifficulty(td) self.setTotalDifficulty(td)
self.insert(block) self.insert(block)
self.transState = state.New(cblock.Trie().Copy()) self.transState = state.New(cblock.Root(), self.db) //state.New(cblock.Trie().Copy())
} }
} }

View file

@ -21,14 +21,6 @@ func init() {
ethutil.ReadConfig("/tmp/ethtest", "/tmp/ethtest", "ETH") ethutil.ReadConfig("/tmp/ethtest", "/tmp/ethtest", "ETH")
} }
func reset() {
db, err := ethdb.NewMemDatabase()
if err != nil {
panic("Could not create mem-db, failing")
}
ethutil.Config.Db = db
}
func loadChain(fn string, t *testing.T) (types.Blocks, error) { func loadChain(fn string, t *testing.T) (types.Blocks, error) {
fh, err := os.OpenFile(path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "_data", fn), os.O_RDONLY, os.ModePerm) fh, err := os.OpenFile(path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "_data", fn), os.O_RDONLY, os.ModePerm)
if err != nil { if err != nil {
@ -54,7 +46,7 @@ func insertChain(done chan bool, chainMan *ChainManager, chain types.Blocks, t *
} }
func TestChainInsertions(t *testing.T) { func TestChainInsertions(t *testing.T) {
reset() db, _ := ethdb.NewMemDatabase()
chain1, err := loadChain("valid1", t) chain1, err := loadChain("valid1", t)
if err != nil { if err != nil {
@ -69,9 +61,9 @@ func TestChainInsertions(t *testing.T) {
} }
var eventMux event.TypeMux var eventMux event.TypeMux
chainMan := NewChainManager(&eventMux) chainMan := NewChainManager(db, &eventMux)
txPool := NewTxPool(&eventMux) txPool := NewTxPool(&eventMux)
blockMan := NewBlockProcessor(txPool, chainMan, &eventMux) blockMan := NewBlockProcessor(db, txPool, chainMan, &eventMux)
chainMan.SetProcessor(blockMan) chainMan.SetProcessor(blockMan)
const max = 2 const max = 2
@ -94,7 +86,7 @@ func TestChainInsertions(t *testing.T) {
} }
func TestChainMultipleInsertions(t *testing.T) { func TestChainMultipleInsertions(t *testing.T) {
reset() db, _ := ethdb.NewMemDatabase()
const max = 4 const max = 4
chains := make([]types.Blocks, max) chains := make([]types.Blocks, max)
@ -113,9 +105,9 @@ func TestChainMultipleInsertions(t *testing.T) {
} }
} }
var eventMux event.TypeMux var eventMux event.TypeMux
chainMan := NewChainManager(&eventMux) chainMan := NewChainManager(db, &eventMux)
txPool := NewTxPool(&eventMux) txPool := NewTxPool(&eventMux)
blockMan := NewBlockProcessor(txPool, chainMan, &eventMux) blockMan := NewBlockProcessor(db, txPool, chainMan, &eventMux)
chainMan.SetProcessor(blockMan) chainMan.SetProcessor(blockMan)
done := make(chan bool, max) done := make(chan bool, max)
for i, chain := range chains { for i, chain := range chains {

View file

@ -19,7 +19,7 @@ var ZeroHash512 = make([]byte, 64)
var EmptyShaList = crypto.Sha3(ethutil.Encode([]interface{}{})) var EmptyShaList = crypto.Sha3(ethutil.Encode([]interface{}{}))
var EmptyListRoot = crypto.Sha3(ethutil.Encode("")) var EmptyListRoot = crypto.Sha3(ethutil.Encode(""))
func GenesisBlock() *types.Block { func GenesisBlock(db ethutil.Database) *types.Block {
genesis := types.NewBlock(ZeroHash256, ZeroHash160, nil, big.NewInt(131072), crypto.Sha3(big.NewInt(42).Bytes()), "") genesis := types.NewBlock(ZeroHash256, ZeroHash160, nil, big.NewInt(131072), crypto.Sha3(big.NewInt(42).Bytes()), "")
genesis.Header().Number = ethutil.Big0 genesis.Header().Number = ethutil.Big0
genesis.Header().GasLimit = big.NewInt(1000000) genesis.Header().GasLimit = big.NewInt(1000000)
@ -30,7 +30,8 @@ func GenesisBlock() *types.Block {
genesis.SetTransactions(types.Transactions{}) genesis.SetTransactions(types.Transactions{})
genesis.SetReceipts(types.Receipts{}) genesis.SetReceipts(types.Receipts{})
statedb := state.New(genesis.Trie()) statedb := state.New(genesis.Root(), db)
//statedb := state.New(genesis.Trie())
for _, addr := range []string{ for _, addr := range []string{
"51ba59315b3a95761d0863b05ccc7a7f54703d99", "51ba59315b3a95761d0863b05ccc7a7f54703d99",
"e4157b34ea9615cfbde6b4fda419828124b70c78", "e4157b34ea9615cfbde6b4fda419828124b70c78",

View file

@ -77,7 +77,6 @@ func NewTestManager() *TestManager {
fmt.Println("Could not create mem-db, failing") fmt.Println("Could not create mem-db, failing")
return nil return nil
} }
ethutil.Config.Db = db
testManager := &TestManager{} testManager := &TestManager{}
testManager.eventMux = new(event.TypeMux) testManager.eventMux = new(event.TypeMux)

View file

@ -56,11 +56,6 @@ func NewTxPool(eventMux *event.TypeMux) *TxPool {
} }
func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error { func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error {
hash := tx.Hash()
if pool.txs[string(hash)] != nil {
return fmt.Errorf("Known transaction (%x)", hash[0:4])
}
if len(tx.To()) != 0 && len(tx.To()) != 20 { if len(tx.To()) != 0 && len(tx.To()) != 20 {
return fmt.Errorf("Invalid recipient. len = %d", len(tx.To())) return fmt.Errorf("Invalid recipient. len = %d", len(tx.To()))
} }
@ -97,6 +92,10 @@ func (self *TxPool) addTx(tx *types.Transaction) {
} }
func (self *TxPool) Add(tx *types.Transaction) error { func (self *TxPool) Add(tx *types.Transaction) error {
if self.txs[string(tx.Hash())] != nil {
return fmt.Errorf("Known transaction (%x)", tx.Hash()[0:4])
}
err := self.ValidateTransaction(tx) err := self.ValidateTransaction(tx)
if err != nil { if err != nil {
return err return err
@ -149,6 +148,7 @@ func (pool *TxPool) RemoveInvalid(query StateQuery) {
for _, tx := range pool.txs { for _, tx := range pool.txs {
sender := query.GetAccount(tx.From()) sender := query.GetAccount(tx.From())
err := pool.ValidateTransaction(tx) err := pool.ValidateTransaction(tx)
fmt.Println(err, sender.Nonce, tx.Nonce())
if err != nil || sender.Nonce >= tx.Nonce() { if err != nil || sender.Nonce >= tx.Nonce() {
removedTxs = append(removedTxs, tx) removedTxs = append(removedTxs, tx)
} }

View file

@ -6,16 +6,22 @@ import (
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/state"
) )
// State query interface // State query interface
type stateQuery struct{} type stateQuery struct{ db ethutil.Database }
func SQ() stateQuery {
db, _ := ethdb.NewMemDatabase()
return stateQuery{db: db}
}
func (self stateQuery) GetAccount(addr []byte) *state.StateObject { func (self stateQuery) GetAccount(addr []byte) *state.StateObject {
return state.NewStateObject(addr) return state.NewStateObject(addr, self.db)
} }
func transaction() *types.Transaction { func transaction() *types.Transaction {
@ -66,7 +72,7 @@ func TestRemoveInvalid(t *testing.T) {
pool, key := setup() pool, key := setup()
tx1 := transaction() tx1 := transaction()
pool.addTx(tx1) pool.addTx(tx1)
pool.RemoveInvalid(stateQuery{}) pool.RemoveInvalid(SQ())
if pool.Size() > 0 { if pool.Size() > 0 {
t.Error("expected pool size to be 0") t.Error("expected pool size to be 0")
} }
@ -74,7 +80,7 @@ func TestRemoveInvalid(t *testing.T) {
tx1.SetNonce(1) tx1.SetNonce(1)
tx1.SignECDSA(key) tx1.SignECDSA(key)
pool.addTx(tx1) pool.addTx(tx1)
pool.RemoveInvalid(stateQuery{}) pool.RemoveInvalid(SQ())
if pool.Size() != 1 { if pool.Size() != 1 {
t.Error("expected pool size to be 1, is", pool.Size()) t.Error("expected pool size to be 1, is", pool.Size())
} }

View file

@ -9,9 +9,7 @@ import (
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/ptrie"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/state"
) )
type Header struct { type Header struct {
@ -168,16 +166,18 @@ func (self *Block) RlpDataForStorage() interface{} {
} }
// Header accessors (add as you need them) // Header accessors (add as you need them)
func (self *Block) Number() *big.Int { return self.header.Number } func (self *Block) Number() *big.Int { return self.header.Number }
func (self *Block) NumberU64() uint64 { return self.header.Number.Uint64() } func (self *Block) NumberU64() uint64 { return self.header.Number.Uint64() }
func (self *Block) Bloom() []byte { return self.header.Bloom } func (self *Block) Bloom() []byte { return self.header.Bloom }
func (self *Block) Coinbase() []byte { return self.header.Coinbase } func (self *Block) Coinbase() []byte { return self.header.Coinbase }
func (self *Block) Time() int64 { return int64(self.header.Time) } func (self *Block) Time() int64 { return int64(self.header.Time) }
func (self *Block) GasLimit() *big.Int { return self.header.GasLimit } func (self *Block) GasLimit() *big.Int { return self.header.GasLimit }
func (self *Block) GasUsed() *big.Int { return self.header.GasUsed } func (self *Block) GasUsed() *big.Int { return self.header.GasUsed }
func (self *Block) Trie() *ptrie.Trie { return ptrie.New(self.header.Root, ethutil.Config.Db) }
//func (self *Block) Trie() *ptrie.Trie { return ptrie.New(self.header.Root, ethutil.Config.Db) }
//func (self *Block) State() *state.StateDB { return state.New(self.Trie()) }
func (self *Block) Root() []byte { return self.header.Root }
func (self *Block) SetRoot(root []byte) { self.header.Root = root } func (self *Block) SetRoot(root []byte) { self.header.Root = root }
func (self *Block) State() *state.StateDB { return state.New(self.Trie()) }
func (self *Block) Size() ethutil.StorageSize { return ethutil.StorageSize(len(ethutil.Encode(self))) } func (self *Block) Size() ethutil.StorageSize { return ethutil.StorageSize(len(ethutil.Encode(self))) }
// Implement pow.Block // Implement pow.Block

View file

@ -1,6 +1,7 @@
package types package types
import ( import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/ptrie" "github.com/ethereum/go-ethereum/ptrie"
) )
@ -11,7 +12,8 @@ type DerivableList interface {
} }
func DeriveSha(list DerivableList) []byte { func DeriveSha(list DerivableList) []byte {
trie := ptrie.New(nil, ethutil.Config.Db) db, _ := ethdb.NewMemDatabase()
trie := ptrie.New(nil, db)
for i := 0; i < list.Len(); i++ { for i := 0; i < list.Len(); i++ {
trie.Update(ethutil.Encode(i), list.GetRlp(i)) trie.Update(ethutil.Encode(i), list.GetRlp(i))
} }

View file

@ -82,7 +82,7 @@ type Ethereum struct {
func New(config *Config) (*Ethereum, error) { func New(config *Config) (*Ethereum, error) {
// Boostrap database // Boostrap database
logger := ethlogger.New(config.DataDir, config.LogFile, config.LogLevel) logger := ethlogger.New(config.DataDir, config.LogFile, config.LogLevel)
db, err := ethdb.NewLDBDatabase("database") db, err := ethdb.NewLDBDatabase("blockchain")
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -111,7 +111,7 @@ func New(config *Config) (*Ethereum, error) {
clientId := p2p.NewSimpleClientIdentity(config.Name, config.Version, config.Identifier, keyManager.PublicKey()) clientId := p2p.NewSimpleClientIdentity(config.Name, config.Version, config.Identifier, keyManager.PublicKey())
saveProtocolVersion(db) saveProtocolVersion(db)
ethutil.Config.Db = db //ethutil.Config.Db = db
eth := &Ethereum{ eth := &Ethereum{
shutdownChan: make(chan bool), shutdownChan: make(chan bool),
@ -124,9 +124,9 @@ func New(config *Config) (*Ethereum, error) {
logger: logger, logger: logger,
} }
eth.chainManager = core.NewChainManager(eth.EventMux()) eth.chainManager = core.NewChainManager(db, eth.EventMux())
eth.txPool = core.NewTxPool(eth.EventMux()) eth.txPool = core.NewTxPool(eth.EventMux())
eth.blockProcessor = core.NewBlockProcessor(eth.txPool, eth.chainManager, eth.EventMux()) eth.blockProcessor = core.NewBlockProcessor(db, eth.txPool, eth.chainManager, eth.EventMux())
eth.chainManager.SetProcessor(eth.blockProcessor) eth.chainManager.SetProcessor(eth.blockProcessor)
eth.whisper = whisper.New() eth.whisper = whisper.New()

View file

@ -122,7 +122,7 @@ func (self *ethProtocol) handle() error {
defer msg.Discard() defer msg.Discard()
switch msg.Code { switch msg.Code {
case GetTxMsg: // ignore
case StatusMsg: case StatusMsg:
return self.protoError(ErrExtraStatusMsg, "") return self.protoError(ErrExtraStatusMsg, "")

View file

@ -10,8 +10,6 @@ import (
// Config struct // Config struct
type ConfigManager struct { type ConfigManager struct {
Db Database
ExecPath string ExecPath string
Debug bool Debug bool
Diff bool Diff bool

View file

@ -129,10 +129,9 @@ func (self *JSRE) initStdFuncs() {
*/ */
func (self *JSRE) dump(call otto.FunctionCall) otto.Value { func (self *JSRE) dump(call otto.FunctionCall) otto.Value {
var state *state.StateDB var block *types.Block
if len(call.ArgumentList) > 0 { if len(call.ArgumentList) > 0 {
var block *types.Block
if call.Argument(0).IsNumber() { if call.Argument(0).IsNumber() {
num, _ := call.Argument(0).ToInteger() num, _ := call.Argument(0).ToInteger()
block = self.ethereum.ChainManager().GetBlockByNumber(uint64(num)) block = self.ethereum.ChainManager().GetBlockByNumber(uint64(num))
@ -149,12 +148,12 @@ func (self *JSRE) dump(call otto.FunctionCall) otto.Value {
return otto.UndefinedValue() return otto.UndefinedValue()
} }
state = block.State()
} else { } else {
state = self.ethereum.ChainManager().State() block = self.ethereum.ChainManager().CurrentBlock()
} }
v, _ := self.Vm.ToValue(state.Dump()) statedb := state.New(block.Root(), self.ethereum.Db())
v, _ := self.Vm.ToValue(statedb.Dump())
return v return v
} }

View file

@ -31,6 +31,7 @@ import (
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/pow" "github.com/ethereum/go-ethereum/pow"
"github.com/ethereum/go-ethereum/pow/ezp" "github.com/ethereum/go-ethereum/pow/ezp"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
@ -178,6 +179,7 @@ func (self *Miner) mine() {
blockProcessor = self.eth.BlockProcessor() blockProcessor = self.eth.BlockProcessor()
chainMan = self.eth.ChainManager() chainMan = self.eth.ChainManager()
block = chainMan.NewBlock(self.Coinbase) block = chainMan.NewBlock(self.Coinbase)
state = state.New(block.Root(), self.eth.Db())
) )
block.Header().Extra = self.Extra block.Header().Extra = self.Extra
@ -187,13 +189,11 @@ func (self *Miner) mine() {
} }
parent := chainMan.GetBlock(block.ParentHash()) parent := chainMan.GetBlock(block.ParentHash())
coinbase := block.State().GetOrNewStateObject(block.Coinbase()) coinbase := state.GetOrNewStateObject(block.Coinbase())
coinbase.SetGasPool(core.CalcGasLimit(parent, block)) coinbase.SetGasPool(core.CalcGasLimit(parent, block))
transactions := self.finiliseTxs() transactions := self.finiliseTxs()
state := block.State()
// Accumulate all valid transactions and apply them to the new state // Accumulate all valid transactions and apply them to the new state
// Error may be ignored. It's not important during mining // Error may be ignored. It's not important during mining
receipts, txs, _, erroneous, err := blockProcessor.ApplyTransactions(coinbase, state, block, transactions, true) receipts, txs, _, erroneous, err := blockProcessor.ApplyTransactions(coinbase, state, block, transactions, true)

View file

@ -1,12 +0,0 @@
package ar
import (
"math/big"
"github.com/ethereum/go-ethereum/trie"
)
type Block interface {
Trie() *trie.Trie
Diff() *big.Int
}

View file

@ -1,54 +0,0 @@
package ar
import "math/big"
const lenops int64 = 9
type OpsFunc func(a, b *big.Int) *big.Int
var ops [lenops]OpsFunc
func init() {
ops[0] = Add
ops[1] = Mul
ops[2] = Mod
ops[3] = Xor
ops[4] = And
ops[5] = Or
ops[6] = Sub1
ops[7] = XorSub
ops[8] = Rsh
}
func Add(x, y *big.Int) *big.Int {
return new(big.Int).Add(x, y)
}
func Mul(x, y *big.Int) *big.Int {
return new(big.Int).Mul(x, y)
}
func Mod(x, y *big.Int) *big.Int {
return new(big.Int).Mod(x, y)
}
func Xor(x, y *big.Int) *big.Int {
return new(big.Int).Xor(x, y)
}
func And(x, y *big.Int) *big.Int {
return new(big.Int).And(x, y)
}
func Or(x, y *big.Int) *big.Int {
return new(big.Int).Or(x, y)
}
func Sub1(x, y *big.Int) *big.Int {
a := big.NewInt(-1)
a.Sub(a, x)
return a
}
func XorSub(x, y *big.Int) *big.Int {
t := Sub1(x, nil)
return t.Xor(t, y)
}
func Rsh(x, y *big.Int) *big.Int {
return new(big.Int).Rsh(x, uint(y.Uint64()%64))
}

View file

@ -1,122 +0,0 @@
package ar
import (
"math/big"
"github.com/ethereum/go-ethereum/ethutil"
)
type Entry struct {
op OpsFunc
i, j *big.Int
}
type Tape struct {
tape []Entry
block Block
}
func NewTape(block Block) *Tape {
return &Tape{nil, block}
}
func (self *Tape) gen(w, h int64, gen NumberGenerator) {
self.tape = nil
for v := int64(0); v < h; v++ {
op := ops[gen.rand64(lenops).Int64()]
r := gen.rand64(100).Uint64()
var j *big.Int
if r < 20 && v > 20 {
j = self.tape[len(self.tape)-1].i
} else {
j = gen.rand64(w)
}
i := gen.rand64(w)
self.tape = append(self.tape, Entry{op, i, j})
}
}
func (self *Tape) runTape(w, h int64, gen NumberGenerator) *big.Int {
var mem []*big.Int
for i := int64(0); i < w; i++ {
mem = append(mem, gen.rand(ethutil.BigPow(2, 64)))
}
set := func(i, j int) Entry {
entry := self.tape[i*100+j]
mem[entry.i.Uint64()] = entry.op(entry.i, entry.j)
return entry
}
dir := true
for i := 0; i < int(h)/100; i++ {
var entry Entry
if dir {
for j := 0; j < 100; j++ {
entry = set(i, j)
}
} else {
for j := 99; i >= 0; j-- {
entry = set(i, j)
}
}
t := mem[entry.i.Uint64()]
if big.NewInt(2).Cmp(new(big.Int).Mod(t, big.NewInt(37))) < 0 {
dir = !dir
}
}
return Sha3(mem)
}
func (self *Tape) Verify(header, nonce []byte) bool {
n := ethutil.BigD(nonce)
var w int64 = 10000
var h int64 = 150000
gen := Rnd(Sha3([]interface{}{header, new(big.Int).Div(n, big.NewInt(1000))}))
self.gen(w, h, gen)
gen = Rnd(Sha3([]interface{}{header, new(big.Int).Mod(n, big.NewInt(1000))}))
hash := self.runTape(w, h, gen)
it := self.block.Trie().Iterator()
next := it.Next(string(new(big.Int).Mod(hash, ethutil.BigPow(2, 160)).Bytes()))
req := ethutil.BigPow(2, 256)
req.Div(req, self.block.Diff())
return Sha3([]interface{}{hash, next}).Cmp(req) < 0
}
func (self *Tape) Run(header []byte) []byte {
nonce := big.NewInt(0)
var w int64 = 10000
var h int64 = 150000
req := ethutil.BigPow(2, 256)
req.Div(req, self.block.Diff())
for {
if new(big.Int).Mod(nonce, b(1000)).Cmp(b(0)) == 0 {
gen := Rnd(Sha3([]interface{}{header, new(big.Int).Div(nonce, big.NewInt(1000))}))
self.gen(w, h, gen)
}
gen := Rnd(Sha3([]interface{}{header, new(big.Int).Mod(nonce, big.NewInt(1000))}))
hash := self.runTape(w, h, gen)
it := self.block.Trie().Iterator()
next := it.Next(string(new(big.Int).Mod(hash, ethutil.BigPow(2, 160)).Bytes()))
if Sha3([]interface{}{hash, next}).Cmp(req) < 0 {
return nonce.Bytes()
} else {
nonce.Add(nonce, ethutil.Big1)
}
}
}

View file

@ -1,47 +0,0 @@
package ar
import (
"fmt"
"math/big"
"testing"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/trie"
)
type TestBlock struct {
trie *trie.Trie
}
func NewTestBlock() *TestBlock {
db, _ := ethdb.NewMemDatabase()
return &TestBlock{
trie: trie.New(db, ""),
}
}
func (self *TestBlock) Diff() *big.Int {
return b(10)
}
func (self *TestBlock) Trie() *trie.Trie {
return self.trie
}
func (self *TestBlock) Hash() []byte {
a := make([]byte, 32)
a[0] = 10
a[1] = 2
return a
}
func TestPow(t *testing.T) {
entry := make([]byte, 32)
entry[0] = 255
block := NewTestBlock()
pow := NewTape(block)
nonce := pow.Run(block.Hash())
fmt.Println("Found nonce", nonce)
}

View file

@ -1,66 +0,0 @@
package ar
import (
"math/big"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
)
var b = big.NewInt
type Node interface {
Big() *big.Int
}
type ByteNode []byte
func (self ByteNode) Big() *big.Int {
return ethutil.BigD(ethutil.Encode([]byte(self)))
}
func Sha3(v interface{}) *big.Int {
if b, ok := v.(*big.Int); ok {
return ethutil.BigD(crypto.Sha3(b.Bytes()))
} else if b, ok := v.([]interface{}); ok {
return ethutil.BigD(crypto.Sha3(ethutil.Encode(b)))
} else if s, ok := v.([]*big.Int); ok {
v := make([]interface{}, len(s))
for i, b := range s {
v[i] = b
}
return ethutil.BigD(crypto.Sha3(ethutil.Encode(v)))
}
return nil
}
type NumberGenerator interface {
rand(r *big.Int) *big.Int
rand64(r int64) *big.Int
}
type rnd struct {
seed *big.Int
}
func Rnd(s *big.Int) rnd {
return rnd{s}
}
func (self rnd) rand(r *big.Int) *big.Int {
o := b(0).Mod(self.seed, r)
self.seed.Div(self.seed, r)
if self.seed.Cmp(ethutil.BigPow(2, 64)) < 0 {
self.seed = Sha3(self.seed)
}
return o
}
func (self rnd) rand64(r int64) *big.Int {
return self.rand(b(r))
}

View file

@ -28,7 +28,7 @@ func (self *StateDB) Dump() []byte {
it := self.trie.Iterator() it := self.trie.Iterator()
for it.Next() { for it.Next() {
stateObject := NewStateObjectFromBytes(it.Key, it.Value) stateObject := NewStateObjectFromBytes(it.Key, it.Value, self.db)
account := Account{Balance: stateObject.balance.String(), Nonce: stateObject.Nonce, Root: ethutil.Bytes2Hex(stateObject.Root()), CodeHash: ethutil.Bytes2Hex(stateObject.codeHash)} account := Account{Balance: stateObject.balance.String(), Nonce: stateObject.Nonce, Root: ethutil.Bytes2Hex(stateObject.Root()), CodeHash: ethutil.Bytes2Hex(stateObject.codeHash)}
account.Storage = make(map[string]string) account.Storage = make(map[string]string)

View file

@ -28,6 +28,7 @@ func (self Storage) Copy() Storage {
} }
type StateObject struct { type StateObject struct {
db ethutil.Database
// Address of the object // Address of the object
address []byte address []byte
// Shared attributes // Shared attributes
@ -57,28 +58,20 @@ func (self *StateObject) Reset() {
self.State.Reset() self.State.Reset()
} }
func NewStateObject(addr []byte) *StateObject { func NewStateObject(addr []byte, db ethutil.Database) *StateObject {
// This to ensure that it has 20 bytes (and not 0 bytes), thus left or right pad doesn't matter. // This to ensure that it has 20 bytes (and not 0 bytes), thus left or right pad doesn't matter.
address := ethutil.Address(addr) address := ethutil.Address(addr)
object := &StateObject{address: address, balance: new(big.Int), gasPool: new(big.Int)} object := &StateObject{db: db, address: address, balance: new(big.Int), gasPool: new(big.Int)}
object.State = New(ptrie.New(nil, ethutil.Config.Db)) //New(trie.New(ethutil.Config.Db, "")) object.State = New(nil, db) //New(trie.New(ethutil.Config.Db, ""))
object.storage = make(Storage) object.storage = make(Storage)
object.gasPool = new(big.Int) object.gasPool = new(big.Int)
return object return object
} }
func NewContract(address []byte, balance *big.Int, root []byte) *StateObject { func NewStateObjectFromBytes(address, data []byte, db ethutil.Database) *StateObject {
contract := NewStateObject(address) object := &StateObject{address: address, db: db}
contract.balance = balance
contract.State = New(ptrie.New(nil, ethutil.Config.Db)) //New(trie.New(ethutil.Config.Db, string(root)))
return contract
}
func NewStateObjectFromBytes(address, data []byte) *StateObject {
object := &StateObject{address: address}
object.RlpDecode(data) object.RlpDecode(data)
return object return object
@ -242,7 +235,7 @@ func (self *StateObject) RefundGas(gas, price *big.Int) {
} }
func (self *StateObject) Copy() *StateObject { func (self *StateObject) Copy() *StateObject {
stateObject := NewStateObject(self.Address()) stateObject := NewStateObject(self.Address(), self.db)
stateObject.balance.Set(self.balance) stateObject.balance.Set(self.balance)
stateObject.codeHash = ethutil.CopyBytes(self.codeHash) stateObject.codeHash = ethutil.CopyBytes(self.codeHash)
stateObject.Nonce = self.Nonce stateObject.Nonce = self.Nonce
@ -310,13 +303,13 @@ func (c *StateObject) RlpDecode(data []byte) {
c.Nonce = decoder.Get(0).Uint() c.Nonce = decoder.Get(0).Uint()
c.balance = decoder.Get(1).BigInt() c.balance = decoder.Get(1).BigInt()
c.State = New(ptrie.New(decoder.Get(2).Bytes(), ethutil.Config.Db)) //New(trie.New(ethutil.Config.Db, decoder.Get(2).Interface())) c.State = New(decoder.Get(2).Bytes(), c.db) //New(trie.New(ethutil.Config.Db, decoder.Get(2).Interface()))
c.storage = make(map[string]*ethutil.Value) c.storage = make(map[string]*ethutil.Value)
c.gasPool = new(big.Int) c.gasPool = new(big.Int)
c.codeHash = decoder.Get(3).Bytes() c.codeHash = decoder.Get(3).Bytes()
c.Code, _ = ethutil.Config.Db.Get(c.codeHash) c.Code, _ = c.db.Get(c.codeHash)
} }
// Storage change object. Used by the manifest for notifying changes to // Storage change object. Used by the manifest for notifying changes to

View file

@ -5,7 +5,6 @@ import (
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/ptrie"
) )
type StateSuite struct { type StateSuite struct {
@ -25,10 +24,9 @@ func (s *StateSuite) TestDump(c *checker.C) {
} }
func (s *StateSuite) SetUpTest(c *checker.C) { func (s *StateSuite) SetUpTest(c *checker.C) {
db, _ := ethdb.NewMemDatabase()
ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "") ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "")
ethutil.Config.Db = db db, _ := ethdb.NewMemDatabase()
s.state = New(ptrie.New(nil, db)) s.state = New(nil, db)
} }
func (s *StateSuite) TestSnapshot(c *checker.C) { func (s *StateSuite) TestSnapshot(c *checker.C) {

View file

@ -17,7 +17,7 @@ var statelogger = logger.NewLogger("STATE")
// * Contracts // * Contracts
// * Accounts // * Accounts
type StateDB struct { type StateDB struct {
//Trie *trie.Trie db ethutil.Database
trie *ptrie.Trie trie *ptrie.Trie
stateObjects map[string]*StateObject stateObjects map[string]*StateObject
@ -30,8 +30,10 @@ type StateDB struct {
} }
// Create a new state from a given trie // Create a new state from a given trie
func New(trie *ptrie.Trie) *StateDB { //func New(trie *ptrie.Trie) *StateDB {
return &StateDB{trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string]*big.Int)} func New(root []byte, db ethutil.Database) *StateDB {
trie := ptrie.New(root, db)
return &StateDB{db: db, trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string]*big.Int)}
} }
func (self *StateDB) EmptyLogs() { func (self *StateDB) EmptyLogs() {
@ -138,7 +140,7 @@ func (self *StateDB) UpdateStateObject(stateObject *StateObject) {
addr := stateObject.Address() addr := stateObject.Address()
if len(stateObject.CodeHash()) > 0 { if len(stateObject.CodeHash()) > 0 {
ethutil.Config.Db.Put(stateObject.CodeHash(), stateObject.Code) self.db.Put(stateObject.CodeHash(), stateObject.Code)
} }
self.trie.Update(addr, stateObject.RlpEncode()) self.trie.Update(addr, stateObject.RlpEncode())
@ -165,7 +167,7 @@ func (self *StateDB) GetStateObject(addr []byte) *StateObject {
return nil return nil
} }
stateObject = NewStateObjectFromBytes(addr, []byte(data)) stateObject = NewStateObjectFromBytes(addr, []byte(data), self.db)
self.SetStateObject(stateObject) self.SetStateObject(stateObject)
return stateObject return stateObject
@ -191,7 +193,7 @@ func (self *StateDB) NewStateObject(addr []byte) *StateObject {
statelogger.Debugf("(+) %x\n", addr) statelogger.Debugf("(+) %x\n", addr)
stateObject := NewStateObject(addr) stateObject := NewStateObject(addr, self.db)
self.stateObjects[string(addr)] = stateObject self.stateObjects[string(addr)] = stateObject
return stateObject return stateObject
@ -212,7 +214,8 @@ func (s *StateDB) Cmp(other *StateDB) bool {
func (self *StateDB) Copy() *StateDB { func (self *StateDB) Copy() *StateDB {
if self.trie != nil { if self.trie != nil {
state := New(self.trie.Copy()) state := New(nil, self.db)
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()
} }
@ -305,7 +308,7 @@ func (self *StateDB) Update(gasUsed *big.Int) {
// FIXME trie delete is broken // FIXME trie delete is broken
if deleted { if deleted {
valid, t2 := ptrie.ParanoiaCheck(self.trie, ethutil.Config.Db) valid, t2 := ptrie.ParanoiaCheck(self.trie, self.db)
if !valid { if !valid {
statelogger.Infof("Warn: PARANOIA: Different state root during copy %x vs %x\n", self.trie.Root(), t2.Root()) statelogger.Infof("Warn: PARANOIA: Different state root during copy %x vs %x\n", self.trie.Root(), t2.Root())

View file

@ -4673,6 +4673,81 @@
"value" : "100000" "value" : "100000"
} }
}, },
"CallToNameRegistratorZeorSizeMemExpansion" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "10000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"logs" : [
],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000099977",
"code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000527faaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa6020526000600060006000601773945304eb96065b2a98b57a48a06ae28d285a71b56103e8f1600055",
"nonce" : "0",
"storage" : {
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
"balance" : "1636",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"945304eb96065b2a98b57a48a06ae28d285a71b5" : {
"balance" : "46",
"code" : "0x60003554156009570060203560003555",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "999999999999898364",
"code" : "0x",
"nonce" : "1",
"storage" : {
}
}
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000527faaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa6020526000600060006000601773945304eb96065b2a98b57a48a06ae28d285a71b56103e8f1600055",
"nonce" : "0",
"storage" : {
}
},
"945304eb96065b2a98b57a48a06ae28d285a71b5" : {
"balance" : "23",
"code" : "0x60003554156009570060203560003555",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000000000000000000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" : {
"data" : "",
"gasLimit" : "10000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000"
}
},
"CallToReturn1" : { "CallToReturn1" : {
"env" : { "env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
@ -5023,6 +5098,81 @@
"value" : "100000" "value" : "100000"
} }
}, },
"callcodeToNameRegistratorZeroMemExpanion" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "10000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"logs" : [
],
"out" : "0x",
"post" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000100000",
"code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000527faaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa6020526000600060006000601773945304eb96065b2a98b57a48a06ae28d285a71b56103e8f2600055",
"nonce" : "0",
"storage" : {
}
},
"2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : {
"balance" : "1636",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"945304eb96065b2a98b57a48a06ae28d285a71b5" : {
"balance" : "23",
"code" : "0x60003554156009570060203560003555",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "999999999999898364",
"code" : "0x",
"nonce" : "1",
"storage" : {
}
}
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "1000000000000000000",
"code" : "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000527faaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa6020526000600060006000601773945304eb96065b2a98b57a48a06ae28d285a71b56103e8f2600055",
"nonce" : "0",
"storage" : {
}
},
"945304eb96065b2a98b57a48a06ae28d285a71b5" : {
"balance" : "23",
"code" : "0x60003554156009570060203560003555",
"nonce" : "0",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000000000000000000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" : {
"data" : "",
"gasLimit" : "1000000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "100000"
}
},
"callcodeToReturn1" : { "callcodeToReturn1" : {
"env" : { "env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",

View file

@ -1,4 +1,180 @@
{ {
"blockhash257Block" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "257",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x600040600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9897",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x600040600055",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x600040600055",
"nonce" : "0",
"storage" : {
}
}
}
},
"blockhash258Block" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "258",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x600140600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9897",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x600140600055",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x600140600055",
"nonce" : "0",
"storage" : {
}
}
}
},
"blockhashMyBlock" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "1",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x600140600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9897",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x600140600055",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x600140600055",
"nonce" : "0",
"storage" : {
}
}
}
},
"blockhashNotExistingBlock" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "1",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x600240600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9897",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x600240600055",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x600240600055",
"nonce" : "0",
"storage" : {
}
}
}
},
"coinbase" : { "coinbase" : {
"callcreates" : [ "callcreates" : [
], ],
@ -178,51 +354,6 @@
} }
} }
}, },
"prevhash" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x40600055",
"data" : "0x",
"gas" : "10000",
"gasPrice" : "100000000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "9698",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x40600055",
"nonce" : "0",
"storage" : {
"0x" : "0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x40600055",
"nonce" : "0",
"storage" : {
}
}
}
},
"timestamp" : { "timestamp" : {
"callcreates" : [ "callcreates" : [
], ],

View file

@ -416,6 +416,50 @@
} }
} }
}, },
"calldatacopyZeroMemExpansion" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x60006000600037600051600055",
"data" : "0x01234567890abcdef01234567890abcdef",
"gas" : "100000000000",
"gasPrice" : "1000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "99999999892",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x60006000600037600051600055",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x60006000600037600051600055",
"nonce" : "0",
"storage" : {
}
}
}
},
"calldatacopy_DataIndexTooHigh" : { "calldatacopy_DataIndexTooHigh" : {
"callcreates" : [ "callcreates" : [
], ],
@ -953,7 +997,7 @@
} }
} }
}, },
"codecopy1" : { "codecopyZeroMemExpansion" : {
"callcreates" : [ "callcreates" : [
], ],
"env" : { "env" : {
@ -967,31 +1011,30 @@
"exec" : { "exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x386000600039600051600055", "code" : "0x60006000600039600051600055",
"data" : "0x01234567890abcdef01234567890abcdef", "data" : "0x01234567890abcdef01234567890abcdef",
"gas" : "100000000000", "gas" : "100000000000",
"gasPrice" : "1000000000", "gasPrice" : "1000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000" "value" : "1000000000000000000"
}, },
"gas" : "99999999691", "gas" : "99999999892",
"logs" : [ "logs" : [
], ],
"out" : "0x", "out" : "0x",
"post" : { "post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000", "balance" : "1000000000000000000",
"code" : "0x386000600039600051600055", "code" : "0x60006000600039600051600055",
"nonce" : "0", "nonce" : "0",
"storage" : { "storage" : {
"0x" : "0x3860006000396000516000550000000000000000000000000000000000000000"
} }
} }
}, },
"pre" : { "pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000", "balance" : "1000000000000000000",
"code" : "0x386000600039600051600055", "code" : "0x60006000600039600051600055",
"nonce" : "0", "nonce" : "0",
"storage" : { "storage" : {
} }
@ -1146,6 +1189,64 @@
} }
} }
}, },
"extcodecopyZeroMemExpansion" : {
"callcreates" : [
],
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "256",
"currentGasLimit" : "1000000",
"currentNumber" : "0",
"currentTimestamp" : "1",
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x",
"data" : "0x01234567890abcdef01234567890abcdef",
"gas" : "100000000000",
"gasPrice" : "123456789",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "100000000000",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"cd1722f3947def4cf144679da39c4c32bdc35681" : {
"balance" : "1000000000000000000",
"code" : "0x6005600055",
"nonce" : "0",
"storage" : {
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x",
"nonce" : "0",
"storage" : {
}
},
"cd1722f3947def4cf144679da39c4c32bdc35681" : {
"balance" : "1000000000000000000",
"code" : "0x6005600055",
"nonce" : "0",
"storage" : {
}
}
}
},
"extcodecopy_DataIndexTooHigh" : { "extcodecopy_DataIndexTooHigh" : {
"callcreates" : [ "callcreates" : [
], ],

View file

@ -16,5 +16,4 @@ func init() {
logpkg.AddLogSystem(Logger) logpkg.AddLogSystem(Logger)
ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "") ethutil.ReadConfig(".ethtest", "/tmp/ethtest", "")
ethutil.Config.Db, _ = NewMemDatabase()
} }

View file

@ -7,6 +7,7 @@ import (
"testing" "testing"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/state"
@ -38,8 +39,8 @@ func (self Log) Topics() [][]byte {
return t return t
} }
func StateObjectFromAccount(addr string, account Account) *state.StateObject { func StateObjectFromAccount(db ethutil.Database, addr string, account Account) *state.StateObject {
obj := state.NewStateObject(ethutil.Hex2Bytes(addr)) obj := state.NewStateObject(ethutil.Hex2Bytes(addr), db)
obj.SetBalance(ethutil.Big(account.Balance)) obj.SetBalance(ethutil.Big(account.Balance))
if ethutil.IsHex(account.Code) { if ethutil.IsHex(account.Code) {
@ -84,9 +85,10 @@ func RunVmTest(p string, t *testing.T) {
continue continue
} }
*/ */
statedb := state.New(helper.NewTrie()) db, _ := ethdb.NewMemDatabase()
statedb := state.New(nil, db)
for addr, account := range test.Pre { for addr, account := range test.Pre {
obj := StateObjectFromAccount(addr, account) obj := StateObjectFromAccount(db, addr, account)
statedb.SetStateObject(obj) statedb.SetStateObject(obj)
for a, v := range account.Storage { for a, v := range account.Storage {
obj.SetState(helper.FromHex(a), ethutil.NewValue(helper.FromHex(v))) obj.SetState(helper.FromHex(a), ethutil.NewValue(helper.FromHex(v)))

View file

@ -1,5 +1,6 @@
package trie package trie
/*
import ( import (
"bytes" "bytes"
@ -141,3 +142,4 @@ func (self *Iterator) Next(key string) []byte {
return self.Key return self.Key
} }
*/

View file

@ -1,5 +1,6 @@
package trie package trie
/*
import ( import (
"bytes" "bytes"
"fmt" "fmt"
@ -174,11 +175,9 @@ func New(db ethutil.Database, Root interface{}) *Trie {
func (self *Trie) setRoot(root interface{}) { func (self *Trie) setRoot(root interface{}) {
switch t := root.(type) { switch t := root.(type) {
case string: case string:
/* //if t == "" {
if t == "" { // root = crypto.Sha3(ethutil.Encode(""))
root = crypto.Sha3(ethutil.Encode("")) //}
}
*/
self.Root = []byte(t) self.Root = []byte(t)
case []byte: case []byte:
self.Root = root self.Root = root
@ -187,10 +186,6 @@ func (self *Trie) setRoot(root interface{}) {
} }
} }
/*
* Public (query) interface functions
*/
func (t *Trie) Update(key, value string) { func (t *Trie) Update(key, value string) {
t.mut.Lock() t.mut.Lock()
defer t.mut.Unlock() defer t.mut.Unlock()
@ -629,3 +624,4 @@ func (it *TrieIterator) iterateNode(key []byte, currentNode *ethutil.Value, cb E
} }
} }
} }
*/

View file

@ -1,5 +1,6 @@
package trie package trie
/*
import ( import (
"bytes" "bytes"
"encoding/hex" "encoding/hex"
@ -337,59 +338,6 @@ func (s *TrieSuite) TestItems(c *checker.C) {
c.Assert(s.trie.GetRoot(), checker.DeepEquals, ethutil.Hex2Bytes(exp)) c.Assert(s.trie.GetRoot(), checker.DeepEquals, ethutil.Hex2Bytes(exp))
} }
/*
func TestRndCase(t *testing.T) {
_, trie := NewTrie()
data := []struct{ k, v string }{
{"0000000000000000000000000000000000000000000000000000000000000001", "a07573657264617461000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000003", "8453bb5b31"},
{"0000000000000000000000000000000000000000000000000000000000000004", "850218711a00"},
{"0000000000000000000000000000000000000000000000000000000000000005", "9462d7705bd0b3ecbc51a8026a25597cb28a650c79"},
{"0000000000000000000000000000000000000000000000000000000000000010", "947e70f9460402290a3e487dae01f610a1a8218fda"},
{"0000000000000000000000000000000000000000000000000000000000000111", "01"},
{"0000000000000000000000000000000000000000000000000000000000000112", "a053656e6174650000000000000000000000000000000000000000000000000000"},
{"0000000000000000000000000000000000000000000000000000000000000113", "a053656e6174650000000000000000000000000000000000000000000000000000"},
{"53656e6174650000000000000000000000000000000000000000000000000000", "94977e3f62f5e1ed7953697430303a3cfa2b5b736e"},
}
for _, e := range data {
trie.Update(string(ethutil.Hex2Bytes(e.k)), string(ethutil.Hex2Bytes(e.v)))
}
fmt.Printf("root after update %x\n", trie.Root)
trie.NewIterator().Each(func(k string, v *ethutil.Value) {
fmt.Printf("%x %x\n", k, v.Bytes())
})
data = []struct{ k, v string }{
{"0000000000000000000000000000000000000000000000000000000000000112", ""},
{"436974697a656e73000000000000000000000000000000000000000000000001", ""},
{"436f757274000000000000000000000000000000000000000000000000000002", ""},
{"53656e6174650000000000000000000000000000000000000000000000000000", ""},
{"436f757274000000000000000000000000000000000000000000000000000000", ""},
{"53656e6174650000000000000000000000000000000000000000000000000001", ""},
{"0000000000000000000000000000000000000000000000000000000000000113", ""},
{"436974697a656e73000000000000000000000000000000000000000000000000", ""},
{"436974697a656e73000000000000000000000000000000000000000000000002", ""},
{"436f757274000000000000000000000000000000000000000000000000000001", ""},
{"0000000000000000000000000000000000000000000000000000000000000111", ""},
{"53656e6174650000000000000000000000000000000000000000000000000002", ""},
}
for _, e := range data {
trie.Delete(string(ethutil.Hex2Bytes(e.k)))
}
fmt.Printf("root after delete %x\n", trie.Root)
trie.NewIterator().Each(func(k string, v *ethutil.Value) {
fmt.Printf("%x %x\n", k, v.Bytes())
})
fmt.Printf("%x\n", trie.Get(string(ethutil.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000001"))))
}
*/
func TestOtherSomething(t *testing.T) { func TestOtherSomething(t *testing.T) {
_, trie := NewTrie() _, trie := NewTrie()
@ -445,3 +393,4 @@ func BenchmarkUpdate(b *testing.B) {
trie.Update(fmt.Sprintf("aaaaaaaaaaaaaaa%d", i), "value") trie.Update(fmt.Sprintf("aaaaaaaaaaaaaaa%d", i), "value")
} }
} }
*/

247
update-license.go Normal file
View file

@ -0,0 +1,247 @@
// +build none
/*
This command generates GPL license headers on top of all source files.
You can run it once per month, before cutting a release or just
whenever you feel like it.
go run update-license.go
The copyright in each file is assigned to any authors for which git
can find commits in the file's history. It will try to follow renames
throughout history. The author names are mapped and deduplicated using
the .mailmap file. You can use .mailmap to set the canonical name and
address for each author. See git-shortlog(1) for an explanation
of the .mailmap format.
Please review the resulting diff to check whether the correct
copyright assignments are performed.
*/
package main
import (
"bufio"
"bytes"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path"
"regexp"
"runtime"
"sort"
"strings"
"sync"
"text/template"
)
var (
// only files with these extensions will be considered
extensions = []string{".go", ".js", ".qml"}
// paths with any of these prefixes will be skipped
skipPrefixes = []string{"tests/files/", "cmd/mist/assets/ext/", "cmd/mist/assets/muted/"}
// paths with this prefix are licensed as GPL. all other files are LGPL.
gplPrefixes = []string{"cmd/"}
// this regexp must match the entire license comment at the
// beginning of each file.
licenseCommentRE = regexp.MustCompile(`(?s)^/\*\s*(Copyright|This file is part of) .*?\*/\n*`)
// this line is used when git doesn't find any authors for a file
defaultCopyright = "Copyright (C) 2014 Jeffrey Wilcke <jeffrey@ethereum.org>"
)
// this template generates the license comment.
// its input is an info structure.
var licenseT = template.Must(template.New("").Parse(`/*
{{.Copyrights}}
This file is part of go-ethereum
go-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU {{.License}} as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
go-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU {{.License}} for more details.
You should have received a copy of the GNU {{.License}}
along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
`))
type info struct {
file string
mode os.FileMode
authors map[string][]string // map keys are authors, values are years
gpl bool
}
func (i info) Copyrights() string {
var lines []string
for name, years := range i.authors {
lines = append(lines, "Copyright (C) "+strings.Join(years, ", ")+" "+name)
}
if len(lines) == 0 {
lines = []string{defaultCopyright}
}
sort.Strings(lines)
return strings.Join(lines, "\n\t")
}
func (i info) License() string {
if i.gpl {
return "General Public License"
} else {
return "Lesser General Public License"
}
}
func (i info) ShortLicense() string {
if i.gpl {
return "GPL"
} else {
return "LGPL"
}
}
func (i *info) addAuthorYear(name, year string) {
for _, y := range i.authors[name] {
if y == year {
return
}
}
i.authors[name] = append(i.authors[name], year)
sort.Strings(i.authors[name])
}
func main() {
files := make(chan string)
infos := make(chan *info)
wg := new(sync.WaitGroup)
go getFiles(files)
for i := runtime.NumCPU(); i >= 0; i-- {
// getting file info is slow and needs to be parallel
wg.Add(1)
go getInfo(files, infos, wg)
}
go func() { wg.Wait(); close(infos) }()
writeLicenses(infos)
}
func getFiles(out chan<- string) {
cmd := exec.Command("git", "ls-tree", "-r", "--name-only", "HEAD")
err := doLines(cmd, func(line string) {
for _, p := range skipPrefixes {
if strings.HasPrefix(line, p) {
return
}
}
ext := path.Ext(line)
for _, wantExt := range extensions {
if ext == wantExt {
goto send
}
}
return
send:
out <- line
})
if err != nil {
fmt.Println("error getting files:", err)
}
close(out)
}
func getInfo(files <-chan string, out chan<- *info, wg *sync.WaitGroup) {
for file := range files {
stat, err := os.Lstat(file)
if err != nil {
fmt.Printf("ERROR %s: %v\n", file, err)
continue
}
if !stat.Mode().IsRegular() {
continue
}
info, err := fileInfo(file)
if err != nil {
fmt.Printf("ERROR %s: %v\n", file, err)
continue
}
info.mode = stat.Mode()
out <- info
}
wg.Done()
}
func fileInfo(file string) (*info, error) {
info := &info{file: file, authors: make(map[string][]string)}
for _, p := range gplPrefixes {
if strings.HasPrefix(file, p) {
info.gpl = true
break
}
}
cmd := exec.Command("git", "log", "--follow", "--find-copies", "--pretty=format:%aI | %aN <%aE>", "--", file)
err := doLines(cmd, func(line string) {
sep := strings.IndexByte(line, '|')
year, name := line[:4], line[sep+2:]
info.addAuthorYear(name, year)
})
return info, err
}
func writeLicenses(infos <-chan *info) {
buf := new(bytes.Buffer)
for info := range infos {
content, err := ioutil.ReadFile(info.file)
if err != nil {
fmt.Printf("ERROR: couldn't read %s: %v\n", info.file, err)
continue
}
// construct new file content
buf.Reset()
licenseT.Execute(buf, info)
if m := licenseCommentRE.FindIndex(content); m != nil && m[0] == 0 {
buf.Write(content[m[1]:])
} else {
buf.Write(content)
}
if !bytes.Equal(content, buf.Bytes()) {
fmt.Println("writing", info.ShortLicense(), info.file)
if err := ioutil.WriteFile(info.file, buf.Bytes(), info.mode); err != nil {
fmt.Printf("ERROR: couldn't write %s: %v", info.file, err)
}
}
}
}
func doLines(cmd *exec.Cmd, f func(string)) error {
stdout, err := cmd.StdoutPipe()
if err != nil {
return err
}
if err := cmd.Start(); err != nil {
return err
}
s := bufio.NewScanner(stdout)
for s.Scan() {
f(s.Text())
}
if s.Err() != nil {
return s.Err()
}
if err := cmd.Wait(); err != nil {
return fmt.Errorf("%v (for %s)", err, strings.Join(cmd.Args, " "))
}
return nil
}

View file

@ -49,7 +49,7 @@ var (
S256 = ethutil.S256 S256 = ethutil.S256
) )
const MaxCallDepth = 1024 const MaxCallDepth = 1025
func calcMemSize(off, l *big.Int) *big.Int { func calcMemSize(off, l *big.Int) *big.Int {
if l.Cmp(ethutil.Big0) == 0 { if l.Cmp(ethutil.Big0) == 0 {

View file

@ -39,7 +39,7 @@ func NewJSBlock(block *types.Block) *JSBlock {
ptxs := make([]*JSTransaction, len(block.Transactions())) ptxs := make([]*JSTransaction, len(block.Transactions()))
for i, tx := range block.Transactions() { for i, tx := range block.Transactions() {
ptxs[i] = NewJSTx(tx, block.State()) ptxs[i] = NewJSTx(tx)
} }
txlist := ethutil.NewList(ptxs) txlist := ethutil.NewList(ptxs)
@ -76,7 +76,7 @@ func (self *JSBlock) GetTransaction(hash string) *JSTransaction {
return nil return nil
} }
return NewJSTx(tx, self.ref.State()) return NewJSTx(tx)
} }
type JSTransaction struct { type JSTransaction struct {
@ -95,7 +95,7 @@ type JSTransaction struct {
Confirmations int `json:"confirmations"` Confirmations int `json:"confirmations"`
} }
func NewJSTx(tx *types.Transaction, state *state.StateDB) *JSTransaction { func NewJSTx(tx *types.Transaction) *JSTransaction {
hash := ethutil.Bytes2Hex(tx.Hash()) hash := ethutil.Bytes2Hex(tx.Hash())
receiver := ethutil.Bytes2Hex(tx.To()) receiver := ethutil.Bytes2Hex(tx.To())
if receiver == "0000000000000000000000000000000000000000" { if receiver == "0000000000000000000000000000000000000000" {

View file

@ -36,7 +36,7 @@ func (self *World) SafeGet(addr []byte) *Object {
func (self *World) safeGet(addr []byte) *state.StateObject { func (self *World) safeGet(addr []byte) *state.StateObject {
object := self.State().GetStateObject(addr) object := self.State().GetStateObject(addr)
if object == nil { if object == nil {
object = state.NewStateObject(addr) object = state.NewStateObject(addr, self.pipe.obj.Db())
} }
return object return object

View file

@ -81,7 +81,7 @@ func (self *XEth) Execute(addr []byte, data []byte, value, gas, price *ethutil.V
func (self *XEth) ExecuteObject(object *Object, data []byte, value, gas, price *ethutil.Value) ([]byte, error) { func (self *XEth) ExecuteObject(object *Object, data []byte, value, gas, price *ethutil.Value) ([]byte, error) {
var ( var (
initiator = state.NewStateObject(self.obj.KeyManager().KeyPair().Address()) initiator = state.NewStateObject(self.obj.KeyManager().KeyPair().Address(), self.obj.Db())
block = self.chainManager.CurrentBlock() block = self.chainManager.CurrentBlock()
) )