aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ethchain/block_chain.go10
-rw-r--r--ethchain/filter.go95
-rw-r--r--ethutil/value.go4
3 files changed, 54 insertions, 55 deletions
diff --git a/ethchain/block_chain.go b/ethchain/block_chain.go
index c8e5c610e..467c54058 100644
--- a/ethchain/block_chain.go
+++ b/ethchain/block_chain.go
@@ -236,6 +236,16 @@ func (self *BlockChain) GetBlockByNumber(num uint64) *Block {
return block
}
+func (self *BlockChain) GetBlockBack(num uint64) *Block {
+ block := self.CurrentBlock
+
+ for ; num != 0 && block != nil; num-- {
+ block = self.GetBlock(block.PrevHash)
+ }
+
+ return block
+}
+
func (bc *BlockChain) BlockInfoByHash(hash []byte) BlockInfo {
bi := BlockInfo{}
data, _ := ethutil.Config.Db.Get(append(hash, []byte("Info")...))
diff --git a/ethchain/filter.go b/ethchain/filter.go
index d9f1796f4..0a97b3f98 100644
--- a/ethchain/filter.go
+++ b/ethchain/filter.go
@@ -3,6 +3,7 @@ package ethchain
import (
"bytes"
"fmt"
+ "math"
"github.com/ethereum/eth-go/ethstate"
"github.com/ethereum/eth-go/ethutil"
@@ -16,8 +17,8 @@ type data struct {
// Filtering interface
type Filter struct {
eth EthManager
- earliest []byte
- latest []byte
+ earliest int64
+ latest int64
skip int
from, to [][]byte
max int
@@ -38,37 +39,33 @@ func NewFilterFromMap(object map[string]interface{}, eth EthManager) *Filter {
filter := NewFilter(eth)
if object["earliest"] != nil {
- earliest := object["earliest"]
- if e, ok := earliest.(string); ok {
- filter.SetEarliestBlock(ethutil.Hex2Bytes(e))
- } else {
- filter.SetEarliestBlock(earliest)
- }
+ val := ethutil.NewValue(object["earliest"])
+ filter.SetEarliestBlock(val.Int())
}
if object["latest"] != nil {
- latest := object["latest"]
- if l, ok := latest.(string); ok {
- filter.SetLatestBlock(ethutil.Hex2Bytes(l))
- } else {
- filter.SetLatestBlock(latest)
- }
+ val := ethutil.NewValue(object["latest"])
+ filter.SetLatestBlock(val.Int())
}
if object["to"] != nil {
- filter.AddTo(ethutil.Hex2Bytes(object["to"].(string)))
+ val := ethutil.NewValue(object["to"])
+ filter.AddTo(ethutil.Hex2Bytes(val.Str()))
}
if object["from"] != nil {
- filter.AddFrom(ethutil.Hex2Bytes(object["from"].(string)))
+ val := ethutil.NewValue(object["from"])
+ filter.AddFrom(ethutil.Hex2Bytes(val.Str()))
}
if object["max"] != nil {
- filter.SetMax(object["max"].(int))
+ val := ethutil.NewValue(object["max"])
+ filter.SetMax(int(val.Uint()))
}
if object["skip"] != nil {
- filter.SetSkip(object["skip"].(int))
+ val := ethutil.NewValue(object["skip"])
+ filter.SetSkip(int(val.Uint()))
}
if object["altered"] != nil {
@@ -85,30 +82,12 @@ func (self *Filter) AddAltered(id, address []byte) {
// Set the earliest and latest block for filtering.
// -1 = latest block (i.e., the current block)
// hash = particular hash from-to
-func (self *Filter) SetEarliestBlock(earliest interface{}) {
- e := ethutil.NewValue(earliest)
-
- // Check for -1 (latest) otherwise assume bytes
- if e.Int() == -1 {
- self.earliest = self.eth.BlockChain().CurrentBlock.Hash()
- } else if e.Len() > 0 {
- self.earliest = e.Bytes()
- } else {
- panic(fmt.Sprintf("earliest has to be either -1 or a valid hash: %v (%T)", e, e.Val))
- }
+func (self *Filter) SetEarliestBlock(earliest int64) {
+ self.earliest = earliest
}
-func (self *Filter) SetLatestBlock(latest interface{}) {
- l := ethutil.NewValue(latest)
-
- // Check for -1 (latest) otherwise assume bytes
- if l.Int() == -1 {
- self.latest = self.eth.BlockChain().CurrentBlock.Hash()
- } else if l.Len() > 0 {
- self.latest = l.Bytes()
- } else {
- panic(fmt.Sprintf("latest has to be either -1 or a valid hash: %v", l))
- }
+func (self *Filter) SetLatestBlock(latest int64) {
+ self.latest = latest
}
func (self *Filter) SetFrom(addr [][]byte) {
@@ -137,23 +116,27 @@ func (self *Filter) SetSkip(skip int) {
// Run filters messages with the current parameters set
func (self *Filter) Find() []*ethstate.Message {
- var messages []*ethstate.Message
-
- block := self.eth.BlockChain().GetBlock(self.latest)
-
- // skip N blocks (useful for pagination)
- if self.skip > 0 {
- for i := 0; i < i; i++ {
- block = self.eth.BlockChain().GetBlock(block.PrevHash)
- }
+ var earliestBlockNo uint64 = uint64(self.earliest)
+ if self.earliest == -1 {
+ earliestBlockNo = self.eth.BlockChain().CurrentBlock.Number.Uint64()
+ }
+ var latestBlockNo uint64 = uint64(self.latest)
+ if self.latest == -1 {
+ latestBlockNo = self.eth.BlockChain().CurrentBlock.Number.Uint64()
}
- // Start block filtering
- quit := false
- for i := 1; !quit && block != nil; i++ {
- // Mark last check
- if self.max == i || (len(self.earliest) > 0 && bytes.Compare(block.Hash(), self.earliest) == 0) {
+ var (
+ messages []*ethstate.Message
+ block = self.eth.BlockChain().GetBlockByNumber(latestBlockNo)
+ quit bool
+ )
+ for i := 0; !quit && block != nil; i++ {
+ // Quit on latest
+ switch {
+ case block.Number.Uint64() == earliestBlockNo:
quit = true
+ case self.max <= len(messages):
+ break
}
// Use bloom filtering to see if this block is interesting given the
@@ -173,7 +156,9 @@ func (self *Filter) Find() []*ethstate.Message {
block = self.eth.BlockChain().GetBlock(block.PrevHash)
}
- return messages
+ skip := int(math.Min(float64(len(messages)), float64(self.skip)))
+
+ return messages[skip:]
}
func includes(addresses [][]byte, a []byte) (found bool) {
diff --git a/ethutil/value.go b/ethutil/value.go
index b1f887f29..dd777fa43 100644
--- a/ethutil/value.go
+++ b/ethutil/value.go
@@ -63,6 +63,10 @@ func (val *Value) Uint() uint64 {
return uint64(Val)
} else if Val, ok := val.Val.(uint64); ok {
return Val
+ } else if Val, ok := val.Val.(float32); ok {
+ return uint64(Val)
+ } else if Val, ok := val.Val.(float64); ok {
+ return uint64(Val)
} else if Val, ok := val.Val.(int); ok {
return uint64(Val)
} else if Val, ok := val.Val.(uint); ok {