aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/ethereum/flags.go2
-rw-r--r--cmd/ethereum/main.go2
-rw-r--r--cmd/mist/main.go1
-rw-r--r--core/block_processor.go6
-rw-r--r--core/block_processor_test.go34
-rw-r--r--core/chain_manager.go16
-rw-r--r--core/error.go6
-rw-r--r--core/types/block.go12
-rw-r--r--eth/backend.go6
-rw-r--r--ethutil/number/int.go181
-rw-r--r--ethutil/number/uint_test.go92
-rw-r--r--pow/ezp/pow.go2
-rw-r--r--vm/vm.go5
13 files changed, 350 insertions, 15 deletions
diff --git a/cmd/ethereum/flags.go b/cmd/ethereum/flags.go
index 1e6869a69..577bee442 100644
--- a/cmd/ethereum/flags.go
+++ b/cmd/ethereum/flags.go
@@ -132,7 +132,7 @@ func Init() {
natstr = flag.String("nat", "any", "port mapping mechanism (any|none|upnp|pmp|extip:<IP>)")
)
flag.BoolVar(&Dial, "dial", true, "dial out connections (default on)")
- flag.BoolVar(&SHH, "shh", true, "run whisper protocol (default on)")
+ //flag.BoolVar(&SHH, "shh", true, "run whisper protocol (default on)")
flag.StringVar(&OutboundPort, "port", "30303", "listening port")
flag.StringVar(&BootNodes, "bootnodes", "", "space-separated node URLs for discovery bootstrap")
diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go
index d4a57ee48..1f1a0b761 100644
--- a/cmd/ethereum/main.go
+++ b/cmd/ethereum/main.go
@@ -72,7 +72,7 @@ func main() {
Port: OutboundPort,
NAT: NAT,
KeyRing: KeyRing,
- Shh: SHH,
+ Shh: true,
Dial: Dial,
BootNodes: BootNodes,
NodeKey: NodeKey,
diff --git a/cmd/mist/main.go b/cmd/mist/main.go
index 32222fbef..14f561e99 100644
--- a/cmd/mist/main.go
+++ b/cmd/mist/main.go
@@ -60,6 +60,7 @@ func run() error {
MaxPeers: MaxPeer,
Port: OutboundPort,
NAT: NAT,
+ Shh: true,
BootNodes: BootNodes,
NodeKey: NodeKey,
KeyRing: KeyRing,
diff --git a/core/block_processor.go b/core/block_processor.go
index 893c586dd..b4449100f 100644
--- a/core/block_processor.go
+++ b/core/block_processor.go
@@ -250,7 +250,11 @@ func (sm *BlockProcessor) ValidateBlock(block, parent *types.Block) error {
}
if block.Time() > time.Now().Unix() {
- return fmt.Errorf("block time is in the future")
+ return BlockFutureErr
+ }
+
+ if new(big.Int).Sub(block.Number(), parent.Number()).Cmp(big.NewInt(1)) != 0 {
+ return BlockNumberErr
}
// Verify the nonce of the block. Return an error if it's not valid
diff --git a/core/block_processor_test.go b/core/block_processor_test.go
new file mode 100644
index 000000000..35aeaa714
--- /dev/null
+++ b/core/block_processor_test.go
@@ -0,0 +1,34 @@
+package core
+
+import (
+ "math/big"
+ "testing"
+
+ "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/ethereum/go-ethereum/event"
+)
+
+func proc() (*BlockProcessor, *ChainManager) {
+ db, _ := ethdb.NewMemDatabase()
+ var mux event.TypeMux
+
+ chainMan := NewChainManager(db, &mux)
+ return NewBlockProcessor(db, nil, chainMan, &mux), chainMan
+}
+
+func TestNumber(t *testing.T) {
+ bp, chain := proc()
+ block1 := chain.NewBlock(nil)
+ block1.Header().Number = big.NewInt(3)
+
+ err := bp.ValidateBlock(block1, chain.Genesis())
+ if err != BlockNumberErr {
+ t.Errorf("expected block number error")
+ }
+
+ block1 = chain.NewBlock(nil)
+ err = bp.ValidateBlock(block1, chain.Genesis())
+ if err == BlockNumberErr {
+ t.Errorf("didn't expect block number error")
+ }
+}
diff --git a/core/chain_manager.go b/core/chain_manager.go
index 22d54be03..286282064 100644
--- a/core/chain_manager.go
+++ b/core/chain_manager.go
@@ -87,6 +87,14 @@ type ChainManager struct {
transState *state.StateDB
}
+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
+}
+
func (self *ChainManager) Td() *big.Int {
self.mu.RLock()
defer self.mu.RUnlock()
@@ -108,14 +116,6 @@ func (self *ChainManager) CurrentBlock() *types.Block {
return self.currentBlock
}
-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
-}
-
func (self *ChainManager) Status() (td *big.Int, currentBlock []byte, genesisBlock []byte) {
self.mu.RLock()
defer self.mu.RUnlock()
diff --git a/core/error.go b/core/error.go
index 11d8c1653..6af48ac2d 100644
--- a/core/error.go
+++ b/core/error.go
@@ -1,10 +1,16 @@
package core
import (
+ "errors"
"fmt"
"math/big"
)
+var (
+ BlockNumberErr = errors.New("block number invalid")
+ BlockFutureErr = errors.New("block time is in the future")
+)
+
// Parent error. In case a parent is unknown this error will be thrown
// by the block manager
type ParentErr struct {
diff --git a/core/types/block.go b/core/types/block.go
index fa28f5cc7..d57de1311 100644
--- a/core/types/block.go
+++ b/core/types/block.go
@@ -185,6 +185,18 @@ func (self *Block) GasUsed() *big.Int { return self.header.GasUsed }
func (self *Block) Root() []byte { return self.header.Root }
func (self *Block) SetRoot(root []byte) { self.header.Root = root }
func (self *Block) Size() ethutil.StorageSize { return ethutil.StorageSize(len(ethutil.Encode(self))) }
+func (self *Block) GetTransaction(i int) *Transaction {
+ if len(self.transactions) > i {
+ return self.transactions[i]
+ }
+ return nil
+}
+func (self *Block) GetUncle(i int) *Header {
+ if len(self.uncles) > i {
+ return self.uncles[i]
+ }
+ return nil
+}
// Implement pow.Block
func (self *Block) Difficulty() *big.Int { return self.header.Difficulty }
diff --git a/eth/backend.go b/eth/backend.go
index 06c64e811..4c3ec0053 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -160,7 +160,11 @@ func New(config *Config) (*Ethereum, error) {
eth.blockPool = NewBlockPool(hasBlock, insertChain, ezp.Verify)
ethProto := EthProtocol(eth.txPool, eth.chainManager, eth.blockPool)
- protocols := []p2p.Protocol{ethProto, eth.whisper.Protocol()}
+ protocols := []p2p.Protocol{ethProto}
+ if config.Shh {
+ protocols = append(protocols, eth.whisper.Protocol())
+ }
+
netprv := config.NodeKey
if netprv == nil {
if netprv, err = crypto.GenerateKey(); err != nil {
diff --git a/ethutil/number/int.go b/ethutil/number/int.go
new file mode 100644
index 000000000..9a41fe3e5
--- /dev/null
+++ b/ethutil/number/int.go
@@ -0,0 +1,181 @@
+package number
+
+import (
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/ethutil"
+)
+
+var tt256 = new(big.Int).Lsh(big.NewInt(1), 256)
+var tt256m1 = new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(1))
+var tt255 = new(big.Int).Lsh(big.NewInt(1), 255)
+
+func limitUnsigned256(x *Number) *Number {
+ x.num.And(x.num, tt256m1)
+ return x
+}
+
+func limitSigned256(x *Number) *Number {
+ if x.num.Cmp(tt255) < 0 {
+ return x
+ } else {
+ x.num.Sub(x.num, tt256)
+ return x
+ }
+}
+
+// Number function
+type Initialiser func(n int64) *Number
+
+// A Number represents a generic integer with a bounding function limiter. Limit is called after each operations
+// to give "fake" bounded integers. New types of Number can be created through NewInitialiser returning a lambda
+// with the new Initialiser.
+type Number struct {
+ num *big.Int
+ limit func(n *Number) *Number
+}
+
+// Returns a new initialiser for a new *Number without having to expose certain fields
+func NewInitialiser(limiter func(*Number) *Number) Initialiser {
+ return func(n int64) *Number {
+ return &Number{big.NewInt(n), limiter}
+ }
+}
+
+// Return a Number with a UNSIGNED limiter up to 256 bits
+func Uint256(n int64) *Number {
+ return &Number{big.NewInt(n), limitUnsigned256}
+}
+
+// Return a Number with a SIGNED limiter up to 256 bits
+func Int256(n int64) *Number {
+ return &Number{big.NewInt(n), limitSigned256}
+}
+
+// Returns a Number with a SIGNED unlimited size
+func Big(n int64) *Number {
+ return &Number{big.NewInt(n), func(x *Number) *Number { return x }}
+}
+
+// Sets i to sum of x+y
+func (i *Number) Add(x, y *Number) *Number {
+ i.num.Add(x.num, y.num)
+ return i.limit(i)
+}
+
+// Sets i to difference of x-y
+func (i *Number) Sub(x, y *Number) *Number {
+ i.num.Sub(x.num, y.num)
+ return i.limit(i)
+}
+
+// Sets i to product of x*y
+func (i *Number) Mul(x, y *Number) *Number {
+ i.num.Mul(x.num, y.num)
+ return i.limit(i)
+}
+
+// Sets i to the quotient prodject of x/y
+func (i *Number) Div(x, y *Number) *Number {
+ i.num.Div(x.num, y.num)
+ return i.limit(i)
+}
+
+// Sets i to x % y
+func (i *Number) Mod(x, y *Number) *Number {
+ i.num.Mod(x.num, y.num)
+ return i.limit(i)
+}
+
+// Sets i to x << s
+func (i *Number) Lsh(x *Number, s uint) *Number {
+ i.num.Lsh(x.num, s)
+ return i.limit(i)
+}
+
+// Sets i to x^y
+func (i *Number) Pow(x, y *Number) *Number {
+ i.num.Exp(x.num, y.num, big.NewInt(0))
+ return i.limit(i)
+}
+
+// Setters
+
+// Set x to i
+func (i *Number) Set(x *Number) *Number {
+ i.num.Set(x.num)
+ return i.limit(i)
+}
+
+// Set x bytes to i
+func (i *Number) SetBytes(x []byte) *Number {
+ i.num.SetBytes(x)
+ return i.limit(i)
+}
+
+// Cmp compares x and y and returns:
+//
+// -1 if x < y
+// 0 if x == y
+// +1 if x > y
+func (i *Number) Cmp(x *Number) int {
+ return i.num.Cmp(x.num)
+}
+
+// Getters
+
+// Returns the string representation of i
+func (i *Number) String() string {
+ return i.num.String()
+}
+
+// Returns the byte representation of i
+func (i *Number) Bytes() []byte {
+ return i.num.Bytes()
+}
+
+// Uint64 returns the Uint64 representation of x. If x cannot be represented in an int64, the result is undefined.
+func (i *Number) Uint64() uint64 {
+ return i.num.Uint64()
+}
+
+// Int64 returns the int64 representation of x. If x cannot be represented in an int64, the result is undefined.
+func (i *Number) Int64() int64 {
+ return i.num.Int64()
+}
+
+// Returns the signed version of i
+func (i *Number) Int256() *Number {
+ return Int(0).Set(i)
+}
+
+// Returns the unsigned version of i
+func (i *Number) Uint256() *Number {
+ return Uint(0).Set(i)
+}
+
+// Returns the index of the first bit that's set to 1
+func (i *Number) FirstBitSet() int {
+ for j := 0; j < i.num.BitLen(); j++ {
+ if i.num.Bit(j) > 0 {
+ return j
+ }
+ }
+
+ return i.num.BitLen()
+}
+
+// Variables
+
+var (
+ Zero = Uint(0)
+ One = Uint(1)
+ Two = Uint(2)
+ MaxUint256 = Uint(0).SetBytes(ethutil.Hex2Bytes("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"))
+
+ MinOne = Int(-1)
+
+ // "typedefs"
+ Uint = Uint256
+ Int = Int256
+)
diff --git a/ethutil/number/uint_test.go b/ethutil/number/uint_test.go
new file mode 100644
index 000000000..c42989465
--- /dev/null
+++ b/ethutil/number/uint_test.go
@@ -0,0 +1,92 @@
+package number
+
+import (
+ "math/big"
+ "testing"
+
+ "github.com/ethereum/go-ethereum/ethutil"
+)
+
+func TestSet(t *testing.T) {
+ a := Uint(0)
+ b := Uint(10)
+ a.Set(b)
+ if a.num.Cmp(b.num) != 0 {
+ t.Error("didn't compare", a, b)
+ }
+
+ c := Uint(0).SetBytes(ethutil.Hex2Bytes("0a"))
+ if c.num.Cmp(big.NewInt(10)) != 0 {
+ t.Error("c set bytes failed.")
+ }
+}
+
+func TestInitialiser(t *testing.T) {
+ check := false
+ init := NewInitialiser(func(x *Number) *Number {
+ check = true
+ return x
+ })
+ a := init(0).Add(init(1), init(2))
+ if a.Cmp(init(3)) != 0 {
+ t.Error("expected 3. got", a)
+ }
+ if !check {
+ t.Error("expected limiter to be called")
+ }
+}
+
+func TestGet(t *testing.T) {
+ a := Uint(10)
+ if a.Uint64() != 10 {
+ t.Error("expected to get 10. got", a.Uint64())
+ }
+
+ a = Uint(10)
+ if a.Int64() != 10 {
+ t.Error("expected to get 10. got", a.Int64())
+ }
+}
+
+func TestCmp(t *testing.T) {
+ a := Uint(10)
+ b := Uint(10)
+ c := Uint(11)
+
+ if a.Cmp(b) != 0 {
+ t.Error("a b == 0 failed", a, b)
+ }
+
+ if a.Cmp(c) >= 0 {
+ t.Error("a c < 0 failed", a, c)
+ }
+
+ if c.Cmp(b) <= 0 {
+ t.Error("c b > 0 failed", c, b)
+ }
+}
+
+func TestMaxArith(t *testing.T) {
+ a := Uint(0).Add(MaxUint256, One)
+ if a.Cmp(Zero) != 0 {
+ t.Error("expected max256 + 1 = 0 got", a)
+ }
+
+ a = Uint(0).Sub(Uint(0), One)
+ if a.Cmp(MaxUint256) != 0 {
+ t.Error("expected 0 - 1 = max256 got", a)
+ }
+
+ a = Int(0).Sub(Int(0), One)
+ if a.Cmp(MinOne) != 0 {
+ t.Error("expected 0 - 1 = -1 got", a)
+ }
+}
+
+func TestConversion(t *testing.T) {
+ a := Int(-1)
+ b := a.Uint256()
+ if b.Cmp(MaxUint256) != 0 {
+ t.Error("expected -1 => unsigned to return max. got", b)
+ }
+}
diff --git a/pow/ezp/pow.go b/pow/ezp/pow.go
index f4a8b80e5..540381243 100644
--- a/pow/ezp/pow.go
+++ b/pow/ezp/pow.go
@@ -21,7 +21,7 @@ type EasyPow struct {
}
func New() *EasyPow {
- return &EasyPow{turbo: true}
+ return &EasyPow{turbo: false}
}
func (pow *EasyPow) GetHashrate() int64 {
diff --git a/vm/vm.go b/vm/vm.go
index 29e1ade54..5ec507ddc 100644
--- a/vm/vm.go
+++ b/vm/vm.go
@@ -266,7 +266,7 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
base.Sub(Pow256, stack.Pop()).Sub(base, ethutil.Big1)
// Not needed
- //base = U256(base)
+ base = U256(base)
stack.Push(base)
case LT:
@@ -532,7 +532,7 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
case NUMBER:
number := self.env.BlockNumber()
- stack.Push(number)
+ stack.Push(U256(number))
self.Printf(" => 0x%x", number.Bytes())
case DIFFICULTY:
@@ -676,6 +676,7 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
gas := stack.Pop()
// Pop gas and value of the stack.
value, addr := stack.Popn()
+ value = U256(value)
// Pop input size and offset
inSize, inOffset := stack.Popn()
// Pop return size and offset