diff options
-rw-r--r-- | cmd/evm/main.go | 6 | ||||
-rw-r--r-- | cmd/geth/main.go | 46 | ||||
-rw-r--r-- | core/block_processor.go | 15 | ||||
-rw-r--r-- | core/chain_makers.go | 2 | ||||
-rw-r--r-- | core/chain_manager.go | 171 | ||||
-rw-r--r-- | core/chain_manager_test.go | 3 | ||||
-rw-r--r-- | core/chain_util.go | 98 | ||||
-rw-r--r-- | core/transaction_pool.go | 4 | ||||
-rw-r--r-- | core/types/block.go | 2 | ||||
-rw-r--r-- | core/types/block_test.go | 2 | ||||
-rw-r--r-- | core/vm/environment.go | 2 | ||||
-rw-r--r-- | core/vm/vm.go | 2 | ||||
-rw-r--r-- | core/vm_env.go | 2 | ||||
-rw-r--r-- | miner/worker.go | 6 | ||||
-rw-r--r-- | rpc/api/mergedapi.go | 2 | ||||
-rw-r--r-- | tests/util.go | 6 | ||||
-rw-r--r-- | xeth/types.go | 2 |
17 files changed, 216 insertions, 155 deletions
diff --git a/cmd/evm/main.go b/cmd/evm/main.go index 7c9d27fac..f6ec8c21e 100644 --- a/cmd/evm/main.go +++ b/cmd/evm/main.go @@ -106,7 +106,7 @@ type VMEnv struct { depth int Gas *big.Int - time int64 + time uint64 logs []vm.StructLog } @@ -115,7 +115,7 @@ func NewEnv(state *state.StateDB, transactor common.Address, value *big.Int) *VM state: state, transactor: &transactor, value: value, - time: time.Now().Unix(), + time: uint64(time.Now().Unix()), } } @@ -123,7 +123,7 @@ func (self *VMEnv) State() *state.StateDB { return self.state } func (self *VMEnv) Origin() common.Address { return *self.transactor } func (self *VMEnv) BlockNumber() *big.Int { return common.Big0 } func (self *VMEnv) Coinbase() common.Address { return *self.transactor } -func (self *VMEnv) Time() int64 { return self.time } +func (self *VMEnv) Time() uint64 { return self.time } func (self *VMEnv) Difficulty() *big.Int { return common.Big1 } func (self *VMEnv) BlockHash() []byte { return make([]byte, 32) } func (self *VMEnv) Value() *big.Int { return self.value } diff --git a/cmd/geth/main.go b/cmd/geth/main.go index a7b769270..be40d5137 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -37,8 +37,12 @@ import ( "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/rpc/codec" "github.com/ethereum/go-ethereum/rpc/comms" @@ -68,6 +72,18 @@ func init() { app.Action = run app.HideVersion = true // we have a command to print the version app.Commands = []cli.Command{ + { + Action: blockRecovery, + Name: "recover", + Usage: "attempts to recover a corrupted database by setting a new block by number or hash. See help recover.", + Description: ` +The recover commands will attempt to read out the last +block based on that. + +recover #number recovers by number +recover <hex> recovers by hash +`, + }, blocktestCommand, importCommand, exportCommand, @@ -438,6 +454,36 @@ func unlockAccount(ctx *cli.Context, am *accounts.Manager, account string) (pass return } +func blockRecovery(ctx *cli.Context) { + arg := ctx.Args().First() + if len(ctx.Args()) < 1 && len(arg) > 0 { + glog.Fatal("recover requires block number or hash") + } + + cfg := utils.MakeEthConfig(ClientIdentifier, nodeNameVersion, ctx) + blockDb, err := ethdb.NewLDBDatabase(filepath.Join(cfg.DataDir, "blockchain")) + if err != nil { + glog.Fatalln("could not open db:", err) + } + + var block *types.Block + if arg[0] == '#' { + block = core.GetBlockByNumber(blockDb, common.String2Big(arg[1:]).Uint64()) + } else { + block = core.GetBlockByHash(blockDb, common.HexToHash(arg)) + } + + if block == nil { + glog.Fatalln("block not found. Recovery failed") + } + + err = core.WriteHead(blockDb, block) + if err != nil { + glog.Fatalln("block write err", err) + } + glog.Infof("Recovery succesful. New HEAD %x\n", block.Hash()) +} + func startEth(ctx *cli.Context, eth *eth.Ethereum) { // Start Ethereum itself diff --git a/core/block_processor.go b/core/block_processor.go index 22d4c7c27..9b77d10eb 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -362,6 +362,13 @@ func ValidateHeader(pow pow.PoW, block *types.Header, parent *types.Block, check return fmt.Errorf("Block extra data too long (%d)", len(block.Extra)) } + if block.Time > uint64(time.Now().Unix()) { + return BlockFutureErr + } + if block.Time <= parent.Time() { + return BlockEqualTSErr + } + expd := CalcDifficulty(int64(block.Time), int64(parent.Time()), parent.Difficulty()) if expd.Cmp(block.Difficulty) != 0 { return fmt.Errorf("Difficulty check failed for block %v, %v", block.Difficulty, expd) @@ -377,20 +384,12 @@ func ValidateHeader(pow pow.PoW, block *types.Header, parent *types.Block, check return fmt.Errorf("GasLimit check failed for block %v (%v > %v)", block.GasLimit, a, b) } - if int64(block.Time) > time.Now().Unix() { - return BlockFutureErr - } - num := parent.Number() num.Sub(block.Number, num) if num.Cmp(big.NewInt(1)) != 0 { return BlockNumberErr } - if block.Time <= uint64(parent.Time()) { - return BlockEqualTSErr //ValidationError("Block timestamp equal or less than previous block (%v - %v)", block.Time, parent.Time) - } - if checkPow { // Verify the nonce of the block. Return an error if it's not valid if !pow.Verify(types.NewBlockWithHeader(block)) { diff --git a/core/chain_makers.go b/core/chain_makers.go index 72ae7970e..013251d74 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -155,7 +155,7 @@ func makeHeader(parent *types.Block, state *state.StateDB) *types.Header { Root: state.Root(), ParentHash: parent.Hash(), Coinbase: parent.Coinbase(), - Difficulty: CalcDifficulty(time, parent.Time(), parent.Difficulty()), + Difficulty: CalcDifficulty(int64(time), int64(parent.Time()), parent.Difficulty()), GasLimit: CalcGasLimit(parent), GasUsed: new(big.Int), Number: new(big.Int).Add(parent.Number(), common.Big1), diff --git a/core/chain_manager.go b/core/chain_manager.go index 808ccd201..70a8b11c6 100644 --- a/core/chain_manager.go +++ b/core/chain_manager.go @@ -1,7 +1,6 @@ package core import ( - "bytes" "fmt" "io" "math/big" @@ -11,19 +10,15 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/compression/rle" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" "github.com/ethereum/go-ethereum/metrics" - "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/pow" "github.com/ethereum/go-ethereum/rlp" "github.com/hashicorp/golang-lru" - "github.com/syndtr/goleveldb/leveldb" ) var ( @@ -40,55 +35,9 @@ const ( blockCacheLimit = 256 maxFutureBlocks = 256 maxTimeFutureBlocks = 30 + checkpointLimit = 200 ) -// CalcDifficulty is the difficulty adjustment algorithm. It returns -// the difficulty that a new block b should have when created at time -// given the parent block's time and difficulty. -func CalcDifficulty(time int64, parentTime int64, parentDiff *big.Int) *big.Int { - diff := new(big.Int) - adjust := new(big.Int).Div(parentDiff, params.DifficultyBoundDivisor) - if big.NewInt(time-parentTime).Cmp(params.DurationLimit) < 0 { - diff.Add(parentDiff, adjust) - } else { - diff.Sub(parentDiff, adjust) - } - if diff.Cmp(params.MinimumDifficulty) < 0 { - return params.MinimumDifficulty - } - return diff -} - -// CalcTD computes the total difficulty of block. -func CalcTD(block, parent *types.Block) *big.Int { - if parent == nil { - return block.Difficulty() - } - d := block.Difficulty() - d.Add(d, parent.Td) - return d -} - -// CalcGasLimit computes the gas limit of the next block after parent. -// The result may be modified by the caller. -func CalcGasLimit(parent *types.Block) *big.Int { - decay := new(big.Int).Div(parent.GasLimit(), params.GasLimitBoundDivisor) - contrib := new(big.Int).Mul(parent.GasUsed(), big.NewInt(3)) - contrib = contrib.Div(contrib, big.NewInt(2)) - contrib = contrib.Div(contrib, params.GasLimitBoundDivisor) - - gl := new(big.Int).Sub(parent.GasLimit(), decay) - gl = gl.Add(gl, contrib) - gl = gl.Add(gl, big.NewInt(1)) - gl.Set(common.BigMax(gl, params.MinGasLimit)) - - if gl.Cmp(params.GenesisGasLimit) < 0 { - gl.Add(parent.GasLimit(), decay) - gl.Set(common.BigMin(gl, params.GenesisGasLimit)) - } - return gl -} - type ChainManager struct { //eth EthManager blockDb common.Database @@ -101,6 +50,7 @@ type ChainManager struct { chainmu sync.RWMutex tsmu sync.RWMutex + checkpoint int // checkpoint counts towards the new checkpoint td *big.Int currentBlock *types.Block lastBlockHash common.Hash @@ -109,9 +59,8 @@ type ChainManager struct { transState *state.StateDB txState *state.ManagedState - cache *lru.Cache // cache is the LRU caching - futureBlocks *lru.Cache // future blocks are blocks added for later processing - pendingBlocks *lru.Cache // pending blocks contain blocks not yet written to the db + cache *lru.Cache // cache is the LRU caching + futureBlocks *lru.Cache // future blocks are blocks added for later processing quit chan struct{} // procInterrupt must be atomically called @@ -240,6 +189,24 @@ func (self *ChainManager) setTransState(statedb *state.StateDB) { self.transState = statedb } +func (bc *ChainManager) recover() bool { + data, _ := bc.blockDb.Get([]byte("checkpoint")) + if len(data) != 0 { + block := bc.GetBlock(common.BytesToHash(data)) + if block != nil { + err := bc.blockDb.Put([]byte("LastBlock"), block.Hash().Bytes()) + if err != nil { + glog.Fatalln("db write err:", err) + } + + bc.currentBlock = block + bc.lastBlockHash = block.Hash() + return true + } + } + return false +} + func (bc *ChainManager) setLastState() { data, _ := bc.blockDb.Get([]byte("LastBlock")) if len(data) != 0 { @@ -248,7 +215,12 @@ func (bc *ChainManager) setLastState() { bc.currentBlock = block bc.lastBlockHash = block.Hash() } else { - glog.Fatalf("Fatal. LastBlock not found. Please run removedb and resync") + glog.Infof("LastBlock (%x) not found. Recovering...\n", data) + if bc.recover() { + glog.Infof("Recover successful") + } else { + glog.Fatalf("Recover failed. Please report") + } } } else { bc.Reset() @@ -347,14 +319,19 @@ func (self *ChainManager) ExportN(w io.Writer, first uint64, last uint64) error // insert injects a block into the current chain block chain. Note, this function // assumes that the `mu` mutex is held! func (bc *ChainManager) insert(block *types.Block) { - key := append(blockNumPre, block.Number().Bytes()...) - err := bc.blockDb.Put(key, block.Hash().Bytes()) + err := WriteHead(bc.blockDb, block) if err != nil { glog.Fatal("db write fail:", err) } - err = bc.blockDb.Put([]byte("LastBlock"), block.Hash().Bytes()) - if err != nil { - glog.Fatal("db write fail:", err) + + bc.checkpoint++ + if bc.checkpoint > checkpointLimit { + err = bc.blockDb.Put([]byte("checkpoint"), block.Hash().Bytes()) + if err != nil { + glog.Fatal("db write fail:", err) + } + + bc.checkpoint = 0 } bc.currentBlock = block @@ -387,12 +364,6 @@ func (bc *ChainManager) HasBlock(hash common.Hash) bool { return true } - if bc.pendingBlocks != nil { - if _, exist := bc.pendingBlocks.Get(hash); exist { - return true - } - } - data, _ := bc.blockDb.Get(append(blockHashPre, hash[:]...)) return len(data) != 0 } @@ -423,26 +394,15 @@ func (self *ChainManager) GetBlock(hash common.Hash) *types.Block { return block.(*types.Block) } - if self.pendingBlocks != nil { - if block, _ := self.pendingBlocks.Get(hash); block != nil { - return block.(*types.Block) - } - } - - data, _ := self.blockDb.Get(append(blockHashPre, hash[:]...)) - if len(data) == 0 { - return nil - } - var block types.StorageBlock - if err := rlp.Decode(bytes.NewReader(data), &block); err != nil { - glog.V(logger.Error).Infof("invalid block RLP for hash %x: %v", hash, err) + block := GetBlockByHash(self.blockDb, hash) + if block == nil { return nil } // Add the block to the cache - self.cache.Add(hash, (*types.Block)(&block)) + self.cache.Add(hash, (*types.Block)(block)) - return (*types.Block)(&block) + return (*types.Block)(block) } func (self *ChainManager) GetBlockByNumber(num uint64) *types.Block { @@ -468,12 +428,7 @@ func (self *ChainManager) GetBlocksFromHash(hash common.Hash, n int) (blocks []* // non blocking version func (self *ChainManager) getBlockByNumber(num uint64) *types.Block { - key, _ := self.blockDb.Get(append(blockNumPre, big.NewInt(int64(num)).Bytes()...)) - if len(key) == 0 { - return nil - } - - return self.GetBlock(common.BytesToHash(key)) + return GetBlockByNumber(self.blockDb, num) } func (self *ChainManager) GetUnclesInChain(block *types.Block, length int) (uncles []*types.Header) { @@ -519,31 +474,6 @@ func (self *ChainManager) procFutureBlocks() { } } -func (self *ChainManager) enqueueForWrite(block *types.Block) { - self.pendingBlocks.Add(block.Hash(), block) -} - -func (self *ChainManager) flushQueuedBlocks() { - db, batchWrite := self.blockDb.(*ethdb.LDBDatabase) - batch := new(leveldb.Batch) - for _, key := range self.pendingBlocks.Keys() { - b, _ := self.pendingBlocks.Get(key) - block := b.(*types.Block) - - enc, _ := rlp.EncodeToBytes((*types.StorageBlock)(block)) - key := append(blockHashPre, block.Hash().Bytes()...) - if batchWrite { - batch.Put(key, rle.Compress(enc)) - } else { - self.blockDb.Put(key, enc) - } - } - - if batchWrite { - db.LDB().Write(batch, nil) - } -} - type writeStatus byte const ( @@ -586,15 +516,7 @@ func (self *ChainManager) WriteBlock(block *types.Block, queued bool) (status wr status = sideStatTy } - if queued { - // Write block to database. Eventually we'll have to improve on this and throw away blocks that are - // not in the canonical chain. - self.mu.Lock() - self.enqueueForWrite(block) - self.mu.Unlock() - } else { - self.write(block) - } + self.write(block) // Delete from future blocks self.futureBlocks.Remove(block.Hash()) @@ -610,8 +532,6 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) { self.chainmu.Lock() defer self.chainmu.Unlock() - self.pendingBlocks, _ = lru.New(len(chain)) - // A queued approach to delivering events. This is generally // faster than direct delivery and requires much less mutex // acquiring. @@ -629,7 +549,6 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) { // Start the parallel nonce verifier. go verifyNonces(self.pow, chain, nonceQuit, nonceDone) defer close(nonceQuit) - defer self.flushQueuedBlocks() txcount := 0 for i, block := range chain { @@ -673,7 +592,7 @@ func (self *ChainManager) InsertChain(chain types.Blocks) (int, error) { // Allow up to MaxFuture second in the future blocks. If this limit // is exceeded the chain is discarded and processed at a later time // if given. - if max := time.Now().Unix() + maxTimeFutureBlocks; block.Time() > max { + if max := time.Now().Unix() + maxTimeFutureBlocks; int64(block.Time()) > max { return i, fmt.Errorf("%v: BlockFutureErr, %v > %v", BlockFutureErr, block.Time(), max) } diff --git a/core/chain_manager_test.go b/core/chain_manager_test.go index 8b3ea9e85..6869bc746 100644 --- a/core/chain_manager_test.go +++ b/core/chain_manager_test.go @@ -109,8 +109,7 @@ func testChain(chainB types.Blocks, bman *BlockProcessor) (*big.Int, error) { bman.bc.mu.Lock() { - bman.bc.enqueueForWrite(block) - //bman.bc.write(block) + bman.bc.write(block) } bman.bc.mu.Unlock() } diff --git a/core/chain_util.go b/core/chain_util.go new file mode 100644 index 000000000..8051cc47a --- /dev/null +++ b/core/chain_util.go @@ -0,0 +1,98 @@ +package core + +import ( + "bytes" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/logger/glog" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" +) + +// CalcDifficulty is the difficulty adjustment algorithm. It returns +// the difficulty that a new block b should have when created at time +// given the parent block's time and difficulty. +func CalcDifficulty(time int64, parentTime int64, parentDiff *big.Int) *big.Int { + diff := new(big.Int) + adjust := new(big.Int).Div(parentDiff, params.DifficultyBoundDivisor) + if big.NewInt(time-parentTime).Cmp(params.DurationLimit) < 0 { + diff.Add(parentDiff, adjust) + } else { + diff.Sub(parentDiff, adjust) + } + if diff.Cmp(params.MinimumDifficulty) < 0 { + return params.MinimumDifficulty + } + return diff +} + +// CalcTD computes the total difficulty of block. +func CalcTD(block, parent *types.Block) *big.Int { + if parent == nil { + return block.Difficulty() + } + d := block.Difficulty() + d.Add(d, parent.Td) + return d +} + +// CalcGasLimit computes the gas limit of the next block after parent. +// The result may be modified by the caller. +func CalcGasLimit(parent *types.Block) *big.Int { + decay := new(big.Int).Div(parent.GasLimit(), params.GasLimitBoundDivisor) + contrib := new(big.Int).Mul(parent.GasUsed(), big.NewInt(3)) + contrib = contrib.Div(contrib, big.NewInt(2)) + contrib = contrib.Div(contrib, params.GasLimitBoundDivisor) + + gl := new(big.Int).Sub(parent.GasLimit(), decay) + gl = gl.Add(gl, contrib) + gl = gl.Add(gl, big.NewInt(1)) + gl.Set(common.BigMax(gl, params.MinGasLimit)) + + if gl.Cmp(params.GenesisGasLimit) < 0 { + gl.Add(parent.GasLimit(), decay) + gl.Set(common.BigMin(gl, params.GenesisGasLimit)) + } + return gl +} + +// GetBlockByHash returns the block corresponding to the hash or nil if not found +func GetBlockByHash(db common.Database, hash common.Hash) *types.Block { + data, _ := db.Get(append(blockHashPre, hash[:]...)) + if len(data) == 0 { + return nil + } + var block types.StorageBlock + if err := rlp.Decode(bytes.NewReader(data), &block); err != nil { + glog.V(logger.Error).Infof("invalid block RLP for hash %x: %v", hash, err) + return nil + } + return (*types.Block)(&block) +} + +// GetBlockByHash returns the canonical block by number or nil if not found +func GetBlockByNumber(db common.Database, number uint64) *types.Block { + key, _ := db.Get(append(blockNumPre, big.NewInt(int64(number)).Bytes()...)) + if len(key) == 0 { + return nil + } + + return GetBlockByHash(db, common.BytesToHash(key)) +} + +// WriteHead force writes the current head +func WriteHead(db common.Database, block *types.Block) error { + key := append(blockNumPre, block.Number().Bytes()...) + err := db.Put(key, block.Hash().Bytes()) + if err != nil { + return err + } + err = db.Put([]byte("LastBlock"), block.Hash().Bytes()) + if err != nil { + return err + } + return nil +} diff --git a/core/transaction_pool.go b/core/transaction_pool.go index 6a7012c65..ac9027755 100644 --- a/core/transaction_pool.go +++ b/core/transaction_pool.go @@ -65,7 +65,7 @@ func NewTxPool(eventMux *event.TypeMux, currentStateFn stateFn, gasLimitFn func( gasLimit: gasLimitFn, minGasPrice: new(big.Int), pendingState: state.ManageState(currentStateFn()), - events: eventMux.Subscribe(ChainEvent{}, GasPriceChanged{}), + events: eventMux.Subscribe(ChainHeadEvent{}, GasPriceChanged{}), } go pool.eventLoop() @@ -80,7 +80,7 @@ func (pool *TxPool) eventLoop() { pool.mu.Lock() switch ev := ev.(type) { - case ChainEvent: + case ChainHeadEvent: pool.resetState() case GasPriceChanged: pool.minGasPrice = ev.Price diff --git a/core/types/block.go b/core/types/block.go index b7eb700ca..e8919e9a0 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -290,7 +290,7 @@ func (b *Block) MixDigest() common.Hash { return b.header.MixDigest } func (b *Block) Nonce() uint64 { return binary.BigEndian.Uint64(b.header.Nonce[:]) } func (b *Block) Bloom() Bloom { return b.header.Bloom } func (b *Block) Coinbase() common.Address { return b.header.Coinbase } -func (b *Block) Time() int64 { return int64(b.header.Time) } +func (b *Block) Time() uint64 { return b.header.Time } func (b *Block) Root() common.Hash { return b.header.Root } func (b *Block) ParentHash() common.Hash { return b.header.ParentHash } func (b *Block) TxHash() common.Hash { return b.header.TxHash } diff --git a/core/types/block_test.go b/core/types/block_test.go index 03e6881be..e0b98cd26 100644 --- a/core/types/block_test.go +++ b/core/types/block_test.go @@ -31,7 +31,7 @@ func TestBlockEncoding(t *testing.T) { check("Root", block.Root(), common.HexToHash("ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017")) check("Hash", block.Hash(), common.HexToHash("0a5843ac1cb04865017cb35a57b50b07084e5fcee39b5acadade33149f4fff9e")) check("Nonce", block.Nonce(), uint64(0xa13a5a8c8f2bb1c4)) - check("Time", block.Time(), int64(1426516743)) + check("Time", block.Time(), uint64(1426516743)) check("Size", block.Size(), common.StorageSize(len(blockEnc))) tx1 := NewTransaction(0, common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), big.NewInt(10), big.NewInt(50000), big.NewInt(10), nil) diff --git a/core/vm/environment.go b/core/vm/environment.go index c103049a2..0a5891f5c 100644 --- a/core/vm/environment.go +++ b/core/vm/environment.go @@ -17,7 +17,7 @@ type Environment interface { BlockNumber() *big.Int GetHash(n uint64) common.Hash Coinbase() common.Address - Time() int64 + Time() uint64 Difficulty() *big.Int GasLimit() *big.Int Transfer(from, to Account, amount *big.Int) error diff --git a/core/vm/vm.go b/core/vm/vm.go index 9e092300d..ba803683b 100644 --- a/core/vm/vm.go +++ b/core/vm/vm.go @@ -444,7 +444,7 @@ func (self *Vm) Run(context *Context, input []byte) (ret []byte, err error) { case TIMESTAMP: time := self.env.Time() - stack.push(big.NewInt(time)) + stack.push(new(big.Int).SetUint64(time)) case NUMBER: number := self.env.BlockNumber() diff --git a/core/vm_env.go b/core/vm_env.go index 6dd83acde..24a29545f 100644 --- a/core/vm_env.go +++ b/core/vm_env.go @@ -33,7 +33,7 @@ func NewEnv(state *state.StateDB, chain *ChainManager, msg Message, header *type func (self *VMEnv) Origin() common.Address { f, _ := self.msg.From(); return f } func (self *VMEnv) BlockNumber() *big.Int { return self.header.Number } func (self *VMEnv) Coinbase() common.Address { return self.header.Coinbase } -func (self *VMEnv) Time() int64 { return int64(self.header.Time) } +func (self *VMEnv) Time() uint64 { return self.header.Time } func (self *VMEnv) Difficulty() *big.Int { return self.header.Difficulty } func (self *VMEnv) GasLimit() *big.Int { return self.header.GasLimit } func (self *VMEnv) Value() *big.Int { return self.msg.Value() } diff --git a/miner/worker.go b/miner/worker.go index f06b6afa1..90914ddcb 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -368,8 +368,8 @@ func (self *worker) commitNewWork() { tstart := time.Now() parent := self.chain.CurrentBlock() tstamp := tstart.Unix() - if tstamp <= parent.Time() { - tstamp = parent.Time() + 1 + if tstamp <= int64(parent.Time()) { + tstamp = int64(parent.Time()) + 1 } // this will ensure we're not going off too far in the future if now := time.Now().Unix(); tstamp > now+4 { @@ -382,7 +382,7 @@ func (self *worker) commitNewWork() { header := &types.Header{ ParentHash: parent.Hash(), Number: num.Add(num, common.Big1), - Difficulty: core.CalcDifficulty(tstamp, parent.Time(), parent.Difficulty()), + Difficulty: core.CalcDifficulty(int64(tstamp), int64(parent.Time()), parent.Difficulty()), GasLimit: core.CalcGasLimit(parent), GasUsed: new(big.Int), Coinbase: self.coinbase, diff --git a/rpc/api/mergedapi.go b/rpc/api/mergedapi.go index bc4fa32e8..c40716996 100644 --- a/rpc/api/mergedapi.go +++ b/rpc/api/mergedapi.go @@ -42,7 +42,7 @@ func (self *MergedApi) Methods() []string { // Call the correct API's Execute method for the given request func (self *MergedApi) Execute(req *shared.Request) (interface{}, error) { - glog.V(logger.Detail).Infof("rpc method: %s", req.Method) + glog.V(logger.Detail).Infof("%s %s", req.Method, req.Params) if res, _ := self.handle(req); res != nil { return res, nil diff --git a/tests/util.go b/tests/util.go index 67650c188..ccdba57e0 100644 --- a/tests/util.go +++ b/tests/util.go @@ -120,7 +120,7 @@ type Env struct { coinbase common.Address number *big.Int - time int64 + time uint64 difficulty *big.Int gasLimit *big.Int @@ -150,7 +150,7 @@ func NewEnvFromMap(state *state.StateDB, envValues map[string]string, exeValues //env.parent = common.Hex2Bytes(envValues["previousHash"]) env.coinbase = common.HexToAddress(envValues["currentCoinbase"]) env.number = common.Big(envValues["currentNumber"]) - env.time = common.Big(envValues["currentTimestamp"]).Int64() + env.time = common.Big(envValues["currentTimestamp"]).Uint64() env.difficulty = common.Big(envValues["currentDifficulty"]) env.gasLimit = common.Big(envValues["currentGasLimit"]) env.Gas = new(big.Int) @@ -163,7 +163,7 @@ func (self *Env) BlockNumber() *big.Int { return self.number } //func (self *Env) PrevHash() []byte { return self.parent } func (self *Env) Coinbase() common.Address { return self.coinbase } -func (self *Env) Time() int64 { return self.time } +func (self *Env) Time() uint64 { return self.time } func (self *Env) Difficulty() *big.Int { return self.difficulty } func (self *Env) State() *state.StateDB { return self.state } func (self *Env) GasLimit() *big.Int { return self.gasLimit } diff --git a/xeth/types.go b/xeth/types.go index ed64dc45e..1d6a0c5ca 100644 --- a/xeth/types.go +++ b/xeth/types.go @@ -60,7 +60,7 @@ type Block struct { Hash string `json:"hash"` Transactions *common.List `json:"transactions"` Uncles *common.List `json:"uncles"` - Time int64 `json:"time"` + Time uint64 `json:"time"` Coinbase string `json:"coinbase"` Name string `json:"name"` GasLimit string `json:"gasLimit"` |