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

View file

@ -31,6 +31,7 @@ import (
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/state"
)
const (
@ -52,6 +53,11 @@ func main() {
// precedence: code-internal flag default < config file < environment variables < command line
Init() // parsing command line
if PrintVersion {
printVersion()
return
}
utils.InitConfig(VmType, ConfigFile, Datadir, "ETH")
ethereum, err := eth.New(&eth.Config{
@ -98,7 +104,8 @@ func main() {
}
// 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)
@ -137,3 +144,13 @@ func main() {
// this blocks the thread
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 (
"bytes"
"encoding/json"
"io"
"io/ioutil"
"log"
"os"
"strings"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/tests/helper"
@ -41,8 +42,8 @@ type Account struct {
Storage map[string]string
}
func StateObjectFromAccount(addr string, account Account) *state.StateObject {
obj := state.NewStateObject(ethutil.Hex2Bytes(addr))
func StateObjectFromAccount(db ethutil.Database, addr string, account Account) *state.StateObject {
obj := state.NewStateObject(ethutil.Hex2Bytes(addr), db)
obj.SetBalance(ethutil.Big(account.Balance))
if ethutil.IsHex(account.Code) {
@ -64,19 +65,20 @@ type VmTest struct {
Pre map[string]Account
}
func RunVmTest(js string) (failed int) {
func RunVmTest(r io.Reader) (failed int) {
tests := make(map[string]VmTest)
data, _ := ioutil.ReadAll(strings.NewReader(js))
data, _ := ioutil.ReadAll(r)
err := json.Unmarshal(data, &tests)
if err != nil {
log.Fatalln(err)
}
for name, test := range tests {
state := state.New(helper.NewTrie())
db, _ := ethdb.NewMemDatabase()
state := state.New(nil, db)
for addr, account := range test.Pre {
obj := StateObjectFromAccount(addr, account)
obj := StateObjectFromAccount(db, addr, account)
state.SetStateObject(obj)
}
@ -123,9 +125,6 @@ func RunVmTest(js string) (failed int) {
func main() {
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/ethutil"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/ptrie"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/vm"
)
@ -63,7 +62,7 @@ func main() {
ethutil.ReadConfig("/tmp/evmtest", "/tmp/evm", "")
db, _ := ethdb.NewMemDatabase()
statedb := state.New(ptrie.New(nil, db))
statedb := state.New(nil, db)
sender := statedb.NewStateObject([]byte("sender"))
receiver := statedb.NewStateObject([]byte("receiver"))
//receiver.SetCode([]byte(*code))

View file

@ -29,6 +29,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/state"
)
type plugin struct {
@ -121,7 +122,7 @@ func (self *Gui) DumpState(hash, path string) {
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)

View file

@ -117,18 +117,7 @@ func (gui *Gui) Start(assetPath string) {
context.SetVar("eth", gui.uiLib)
context.SetVar("shh", gui.whisper)
// Load the main QML interface
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
}
win, err := gui.showWallet(context)
if err != nil {
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()
// only add the gui guilogger after window is shown otherwise slider wont be shown
if addlog {
logger.AddLogSystem(gui)
}
win.Wait()
// 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 (
ptx = xeth.NewJSTx(tx, gui.xeth.World().State())
ptx = xeth.NewJSTx(tx)
send = nameReg.Storage(tx.From())
rec = nameReg.Storage(tx.To())
s, r string

View file

@ -39,6 +39,7 @@ import (
"github.com/ethereum/go-ethereum/miner"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/xeth"
)
@ -259,7 +260,8 @@ func BlockDo(ethereum *eth.Ethereum, hash []byte) error {
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 {
return err
}

View file

@ -36,6 +36,7 @@ type EthManager interface {
}
type BlockProcessor struct {
db ethutil.Database
// Mutex for locking the block processor. Blocks can only be handled one at a time
mutex sync.Mutex
// Canonical block chain
@ -57,8 +58,9 @@ type BlockProcessor struct {
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{
db: db,
mem: make(map[string]*big.Int),
Pow: ezp.New(),
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) {
sm.lastAttemptedBlock = block
state := state.New(parent.Trie().Copy())
state := state.New(parent.Root(), sm.db)
//state := state.New(parent.Trie().Copy())
// Block validation
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)
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)
}
@ -351,7 +355,8 @@ func (sm *BlockProcessor) GetMessages(block *types.Block) (messages []*state.Mes
var (
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()

View file

@ -25,7 +25,7 @@ func CalcDifficulty(block, parent *types.Block) *big.Int {
bh, ph := block.Header(), parent.Header()
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)
} else {
diff.Add(ph.Difficulty, adjust)
@ -55,6 +55,7 @@ func CalcGasLimit(parent, block *types.Block) *big.Int {
type ChainManager struct {
//eth EthManager
db ethutil.Database
processor types.BlockProcessor
eventMux *event.TypeMux
genesisBlock *types.Block
@ -96,13 +97,9 @@ func (self *ChainManager) CurrentBlock() *types.Block {
return self.currentBlock
}
func NewChainManager(mux *event.TypeMux) *ChainManager {
bc := &ChainManager{}
bc.genesisBlock = GenesisBlock()
bc.eventMux = mux
func NewChainManager(db ethutil.Database, mux *event.TypeMux) *ChainManager {
bc := &ChainManager{db: db, genesisBlock: GenesisBlock(db), eventMux: mux}
bc.setLastBlock()
bc.transState = bc.State().Copy()
return bc
@ -120,7 +117,7 @@ func (self *ChainManager) SetProcessor(proc types.BlockProcessor) {
}
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 {
@ -128,7 +125,7 @@ func (self *ChainManager) TransState() *state.StateDB {
}
func (bc *ChainManager) setLastBlock() {
data, _ := ethutil.Config.Db.Get([]byte("LastBlock"))
data, _ := bc.db.Get([]byte("LastBlock"))
if len(data) != 0 {
var block types.Block
rlp.Decode(bytes.NewReader(data), &block)
@ -137,7 +134,7 @@ func (bc *ChainManager) setLastBlock() {
bc.lastBlockNumber = block.Header().Number.Uint64()
// 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 {
bc.Reset()
}
@ -183,7 +180,7 @@ func (bc *ChainManager) Reset() {
defer bc.mu.Unlock()
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
@ -210,7 +207,7 @@ func (self *ChainManager) Export() []byte {
func (bc *ChainManager) insert(block *types.Block) {
encodedBlock := ethutil.Encode(block)
ethutil.Config.Db.Put([]byte("LastBlock"), encodedBlock)
bc.db.Put([]byte("LastBlock"), encodedBlock)
bc.currentBlock = block
bc.lastBlockHash = block.Hash()
}
@ -219,7 +216,7 @@ func (bc *ChainManager) write(block *types.Block) {
bc.writeBlockInfo(block)
encodedBlock := ethutil.Encode(block)
ethutil.Config.Db.Put(block.Hash(), encodedBlock)
bc.db.Put(block.Hash(), encodedBlock)
}
// Accessors
@ -229,7 +226,7 @@ func (bc *ChainManager) Genesis() *types.Block {
// Block fetching methods
func (bc *ChainManager) HasBlock(hash []byte) bool {
data, _ := ethutil.Config.Db.Get(hash)
data, _ := bc.db.Get(hash)
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 {
data, _ := ethutil.Config.Db.Get(hash)
data, _ := self.db.Get(hash)
if len(data) == 0 {
return nil
}
@ -286,7 +283,7 @@ func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block {
}
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
}
@ -348,7 +345,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) error {
self.setTotalDifficulty(td)
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")
}
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) {
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 {
@ -54,7 +46,7 @@ func insertChain(done chan bool, chainMan *ChainManager, chain types.Blocks, t *
}
func TestChainInsertions(t *testing.T) {
reset()
db, _ := ethdb.NewMemDatabase()
chain1, err := loadChain("valid1", t)
if err != nil {
@ -69,9 +61,9 @@ func TestChainInsertions(t *testing.T) {
}
var eventMux event.TypeMux
chainMan := NewChainManager(&eventMux)
chainMan := NewChainManager(db, &eventMux)
txPool := NewTxPool(&eventMux)
blockMan := NewBlockProcessor(txPool, chainMan, &eventMux)
blockMan := NewBlockProcessor(db, txPool, chainMan, &eventMux)
chainMan.SetProcessor(blockMan)
const max = 2
@ -94,7 +86,7 @@ func TestChainInsertions(t *testing.T) {
}
func TestChainMultipleInsertions(t *testing.T) {
reset()
db, _ := ethdb.NewMemDatabase()
const max = 4
chains := make([]types.Blocks, max)
@ -113,9 +105,9 @@ func TestChainMultipleInsertions(t *testing.T) {
}
}
var eventMux event.TypeMux
chainMan := NewChainManager(&eventMux)
chainMan := NewChainManager(db, &eventMux)
txPool := NewTxPool(&eventMux)
blockMan := NewBlockProcessor(txPool, chainMan, &eventMux)
blockMan := NewBlockProcessor(db, txPool, chainMan, &eventMux)
chainMan.SetProcessor(blockMan)
done := make(chan bool, max)
for i, chain := range chains {

View file

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

View file

@ -77,7 +77,6 @@ func NewTestManager() *TestManager {
fmt.Println("Could not create mem-db, failing")
return nil
}
ethutil.Config.Db = db
testManager := &TestManager{}
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 {
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 {
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 {
if self.txs[string(tx.Hash())] != nil {
return fmt.Errorf("Known transaction (%x)", tx.Hash()[0:4])
}
err := self.ValidateTransaction(tx)
if err != nil {
return err
@ -149,6 +148,7 @@ func (pool *TxPool) RemoveInvalid(query StateQuery) {
for _, tx := range pool.txs {
sender := query.GetAccount(tx.From())
err := pool.ValidateTransaction(tx)
fmt.Println(err, sender.Nonce, tx.Nonce())
if err != nil || sender.Nonce >= tx.Nonce() {
removedTxs = append(removedTxs, tx)
}

View file

@ -6,16 +6,22 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/state"
)
// 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 {
return state.NewStateObject(addr)
return state.NewStateObject(addr, self.db)
}
func transaction() *types.Transaction {
@ -66,7 +72,7 @@ func TestRemoveInvalid(t *testing.T) {
pool, key := setup()
tx1 := transaction()
pool.addTx(tx1)
pool.RemoveInvalid(stateQuery{})
pool.RemoveInvalid(SQ())
if pool.Size() > 0 {
t.Error("expected pool size to be 0")
}
@ -74,7 +80,7 @@ func TestRemoveInvalid(t *testing.T) {
tx1.SetNonce(1)
tx1.SignECDSA(key)
pool.addTx(tx1)
pool.RemoveInvalid(stateQuery{})
pool.RemoveInvalid(SQ())
if pool.Size() != 1 {
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/ethutil"
"github.com/ethereum/go-ethereum/ptrie"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/state"
)
type Header struct {
@ -175,9 +173,11 @@ func (self *Block) Coinbase() []byte { return self.header.Coinbase }
func (self *Block) Time() int64 { return int64(self.header.Time) }
func (self *Block) GasLimit() *big.Int { return self.header.GasLimit }
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) State() *state.StateDB { return state.New(self.Trie()) }
func (self *Block) Size() ethutil.StorageSize { return ethutil.StorageSize(len(ethutil.Encode(self))) }
// Implement pow.Block

View file

@ -1,6 +1,7 @@
package types
import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/ptrie"
)
@ -11,7 +12,8 @@ type DerivableList interface {
}
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++ {
trie.Update(ethutil.Encode(i), list.GetRlp(i))
}

View file

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

View file

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

View file

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

View file

@ -129,10 +129,9 @@ func (self *JSRE) initStdFuncs() {
*/
func (self *JSRE) dump(call otto.FunctionCall) otto.Value {
var state *state.StateDB
var block *types.Block
if len(call.ArgumentList) > 0 {
var block *types.Block
if call.Argument(0).IsNumber() {
num, _ := call.Argument(0).ToInteger()
block = self.ethereum.ChainManager().GetBlockByNumber(uint64(num))
@ -149,12 +148,12 @@ func (self *JSRE) dump(call otto.FunctionCall) otto.Value {
return otto.UndefinedValue()
}
state = block.State()
} 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
}

View file

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

View file

@ -28,6 +28,7 @@ func (self Storage) Copy() Storage {
}
type StateObject struct {
db ethutil.Database
// Address of the object
address []byte
// Shared attributes
@ -57,28 +58,20 @@ func (self *StateObject) 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.
address := ethutil.Address(addr)
object := &StateObject{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 := &StateObject{db: db, address: address, balance: new(big.Int), gasPool: new(big.Int)}
object.State = New(nil, db) //New(trie.New(ethutil.Config.Db, ""))
object.storage = make(Storage)
object.gasPool = new(big.Int)
return object
}
func NewContract(address []byte, balance *big.Int, root []byte) *StateObject {
contract := NewStateObject(address)
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}
func NewStateObjectFromBytes(address, data []byte, db ethutil.Database) *StateObject {
object := &StateObject{address: address, db: db}
object.RlpDecode(data)
return object
@ -242,7 +235,7 @@ func (self *StateObject) RefundGas(gas, price *big.Int) {
}
func (self *StateObject) Copy() *StateObject {
stateObject := NewStateObject(self.Address())
stateObject := NewStateObject(self.Address(), self.db)
stateObject.balance.Set(self.balance)
stateObject.codeHash = ethutil.CopyBytes(self.codeHash)
stateObject.Nonce = self.Nonce
@ -310,13 +303,13 @@ func (c *StateObject) RlpDecode(data []byte) {
c.Nonce = decoder.Get(0).Uint()
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.gasPool = new(big.Int)
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

View file

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

View file

@ -17,7 +17,7 @@ var statelogger = logger.NewLogger("STATE")
// * Contracts
// * Accounts
type StateDB struct {
//Trie *trie.Trie
db ethutil.Database
trie *ptrie.Trie
stateObjects map[string]*StateObject
@ -30,8 +30,10 @@ type StateDB struct {
}
// Create a new state from a given trie
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(trie *ptrie.Trie) *StateDB {
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() {
@ -138,7 +140,7 @@ func (self *StateDB) UpdateStateObject(stateObject *StateObject) {
addr := stateObject.Address()
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())
@ -165,7 +167,7 @@ func (self *StateDB) GetStateObject(addr []byte) *StateObject {
return nil
}
stateObject = NewStateObjectFromBytes(addr, []byte(data))
stateObject = NewStateObjectFromBytes(addr, []byte(data), self.db)
self.SetStateObject(stateObject)
return stateObject
@ -191,7 +193,7 @@ func (self *StateDB) NewStateObject(addr []byte) *StateObject {
statelogger.Debugf("(+) %x\n", addr)
stateObject := NewStateObject(addr)
stateObject := NewStateObject(addr, self.db)
self.stateObjects[string(addr)] = stateObject
return stateObject
@ -212,7 +214,8 @@ func (s *StateDB) Cmp(other *StateDB) bool {
func (self *StateDB) Copy() *StateDB {
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 {
state.stateObjects[k] = stateObject.Copy()
}
@ -305,7 +308,7 @@ func (self *StateDB) Update(gasUsed *big.Int) {
// FIXME trie delete is broken
if deleted {
valid, t2 := ptrie.ParanoiaCheck(self.trie, ethutil.Config.Db)
valid, t2 := ptrie.ParanoiaCheck(self.trie, self.db)
if !valid {
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"
}
},
"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" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
@ -5023,6 +5098,81 @@
"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" : {
"env" : {
"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" : {
"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" : {
"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" : {
"callcreates" : [
],
@ -953,7 +997,7 @@
}
}
},
"codecopy1" : {
"codecopyZeroMemExpansion" : {
"callcreates" : [
],
"env" : {
@ -967,31 +1011,30 @@
"exec" : {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"caller" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"code" : "0x386000600039600051600055",
"code" : "0x60006000600039600051600055",
"data" : "0x01234567890abcdef01234567890abcdef",
"gas" : "100000000000",
"gasPrice" : "1000000000",
"origin" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : "1000000000000000000"
},
"gas" : "99999999691",
"gas" : "99999999892",
"logs" : [
],
"out" : "0x",
"post" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x386000600039600051600055",
"code" : "0x60006000600039600051600055",
"nonce" : "0",
"storage" : {
"0x" : "0x3860006000396000516000550000000000000000000000000000000000000000"
}
}
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : "1000000000000000000",
"code" : "0x386000600039600051600055",
"code" : "0x60006000600039600051600055",
"nonce" : "0",
"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" : {
"callcreates" : [
],

View file

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

View file

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

View file

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

View file

@ -1,5 +1,6 @@
package trie
/*
import (
"bytes"
"fmt"
@ -174,11 +175,9 @@ func New(db ethutil.Database, Root interface{}) *Trie {
func (self *Trie) setRoot(root interface{}) {
switch t := root.(type) {
case string:
/*
if t == "" {
root = crypto.Sha3(ethutil.Encode(""))
}
*/
//if t == "" {
// root = crypto.Sha3(ethutil.Encode(""))
//}
self.Root = []byte(t)
case []byte:
self.Root = root
@ -187,10 +186,6 @@ func (self *Trie) setRoot(root interface{}) {
}
}
/*
* Public (query) interface functions
*/
func (t *Trie) Update(key, value string) {
t.mut.Lock()
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
/*
import (
"bytes"
"encoding/hex"
@ -337,59 +338,6 @@ func (s *TrieSuite) TestItems(c *checker.C) {
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) {
_, trie := NewTrie()
@ -445,3 +393,4 @@ func BenchmarkUpdate(b *testing.B) {
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
)
const MaxCallDepth = 1024
const MaxCallDepth = 1025
func calcMemSize(off, l *big.Int) *big.Int {
if l.Cmp(ethutil.Big0) == 0 {

View file

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

View file

@ -36,7 +36,7 @@ func (self *World) SafeGet(addr []byte) *Object {
func (self *World) safeGet(addr []byte) *state.StateObject {
object := self.State().GetStateObject(addr)
if object == nil {
object = state.NewStateObject(addr)
object = state.NewStateObject(addr, self.pipe.obj.Db())
}
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) {
var (
initiator = state.NewStateObject(self.obj.KeyManager().KeyPair().Address())
initiator = state.NewStateObject(self.obj.KeyManager().KeyPair().Address(), self.obj.Db())
block = self.chainManager.CurrentBlock()
)