Browse Source

Added GetBlock GetUncle with OOB guard

obscuren 10 years ago
parent
commit
655e942597
4 changed files with 59 additions and 9 deletions
  1. 5 1
      core/block_processor.go
  2. 34 0
      core/block_processor_test.go
  3. 8 8
      core/chain_manager.go
  4. 12 0
      core/types/block.go

+ 5 - 1
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

+ 34 - 0
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")
+	}
+}

+ 8 - 8
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()

+ 12 - 0
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 }