aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/evm/main.go6
-rw-r--r--cmd/geth/main.go46
-rw-r--r--core/block_processor.go15
-rw-r--r--core/chain_makers.go2
-rw-r--r--core/chain_manager.go171
-rw-r--r--core/chain_manager_test.go3
-rw-r--r--core/chain_util.go98
-rw-r--r--core/transaction_pool.go4
-rw-r--r--core/types/block.go2
-rw-r--r--core/types/block_test.go2
-rw-r--r--core/vm/environment.go2
-rw-r--r--core/vm/vm.go2
-rw-r--r--core/vm_env.go2
-rw-r--r--miner/worker.go6
-rw-r--r--rpc/api/mergedapi.go2
-rw-r--r--tests/util.go6
-rw-r--r--xeth/types.go2
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"`