Skip to content

Commit

Permalink
BlockFilterArgs
Browse files Browse the repository at this point in the history
  • Loading branch information
tgerring committed Mar 27, 2015
1 parent 2788fb4 commit 9f84c78
Show file tree
Hide file tree
Showing 3 changed files with 319 additions and 62 deletions.
51 changes: 19 additions & 32 deletions rpc/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -471,42 +471,29 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
func toFilterOptions(options *BlockFilterArgs) *core.FilterOptions {
var opts core.FilterOptions

// Convert optional address slice/string to byte slice
if str, ok := options.Address.(string); ok {
opts.Address = []common.Address{common.HexToAddress(str)}
} else if slice, ok := options.Address.([]interface{}); ok {
bslice := make([]common.Address, len(slice))
for i, addr := range slice {
if saddr, ok := addr.(string); ok {
bslice[i] = common.HexToAddress(saddr)
}
}
opts.Address = bslice
}
opts.Address = cAddress(options.Address)
opts.Topics = cTopics(options.Topics)

opts.Earliest = options.Earliest
opts.Latest = options.Latest

topics := make([][]common.Hash, len(options.Topics))
for i, topicDat := range options.Topics {
if slice, ok := topicDat.([]interface{}); ok {
topics[i] = make([]common.Hash, len(slice))
for j, topic := range slice {
topics[i][j] = common.HexToHash(topic.(string))
}
} else if str, ok := topicDat.(string); ok {
topics[i] = []common.Hash{common.HexToHash(str)}
}
}
opts.Topics = topics

return &opts
}

/*
Work() chan<- *types.Block
SetWorkCh(chan<- Work)
Stop()
Start()
Rate() uint64
*/
func cAddress(a []string) []common.Address {
bslice := make([]common.Address, len(a))
for i, addr := range a {
bslice[i] = common.HexToAddress(addr)
}
return bslice
}

func cTopics(t [][]string) [][]common.Hash {
topics := make([][]common.Hash, len(t))
for i, iv := range t {
for j, jv := range iv {
topics[i][j] = common.HexToHash(jv)
}
}
return topics
}
116 changes: 96 additions & 20 deletions rpc/args.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@ import (
"bytes"
"encoding/json"
// "errors"
// "fmt"
"fmt"
"math/big"

"github.com/ethereum/go-ethereum/common"
)

const (
defaultLogLimit = 100
defaultLogOffset = 0
)

func blockHeightFromJson(msg json.RawMessage, number *int64) error {
var raw interface{}
if err := json.Unmarshal(msg, &raw); err != nil {
Expand Down Expand Up @@ -483,20 +488,20 @@ func (args *Sha3Args) UnmarshalJSON(b []byte) (err error) {
type BlockFilterArgs struct {
Earliest int64
Latest int64
Address interface{}
Topics []interface{}
Address []string
Topics [][]string
Skip int
Max int
}

func (args *BlockFilterArgs) UnmarshalJSON(b []byte) (err error) {
var obj []struct {
FromBlock interface{} `json:"fromBlock"`
ToBlock interface{} `json:"toBlock"`
Limit interface{} `json:"limit"`
Offset interface{} `json:"offset"`
Address string `json:"address"`
Topics []interface{} `json:"topics"`
FromBlock interface{} `json:"fromBlock"`
ToBlock interface{} `json:"toBlock"`
Limit interface{} `json:"limit"`
Offset interface{} `json:"offset"`
Address interface{} `json:"address"`
Topics interface{} `json:"topics"`
}

if err = json.Unmarshal(b, &obj); err != nil {
Expand All @@ -516,33 +521,104 @@ func (args *BlockFilterArgs) UnmarshalJSON(b []byte) (err error) {
// return NewDecodeParamError(fmt.Sprintf("ToBlock %v", err))

var num int64
if err := blockHeight(obj[0].FromBlock, &num); err != nil {
return err

// if blank then latest
if obj[0].FromBlock == nil {
num = -1
} else {
if err := blockHeight(obj[0].FromBlock, &num); err != nil {
return err
}
}
// if -2 or other "silly" number, use latest
if num < 0 {
args.Earliest = -1 //latest block
} else {
args.Earliest = num
}

if err := blockHeight(obj[0].ToBlock, &num); err != nil {
return err
// if blank than latest
if obj[0].ToBlock == nil {
num = -1
} else {
if err := blockHeight(obj[0].ToBlock, &num); err != nil {
return err
}
}
args.Latest = num

if err := numString(obj[0].Limit, &num); err != nil {
return err
if obj[0].Limit == nil {
num = defaultLogLimit
} else {
if err := numString(obj[0].Limit, &num); err != nil {
return err
}
}
args.Max = int(num)

if err := numString(obj[0].Offset, &num); err != nil {
return err

if obj[0].Offset == nil {
num = defaultLogOffset
} else {
if err := numString(obj[0].Offset, &num); err != nil {
return err
}
}
args.Skip = int(num)

args.Address = obj[0].Address
args.Topics = obj[0].Topics
if obj[0].Address != nil {
marg, ok := obj[0].Address.([]interface{})
if ok {
v := make([]string, len(marg))
for i, arg := range marg {
argstr, ok := arg.(string)
if !ok {
return NewInvalidTypeError(fmt.Sprintf("address[%d]", i), "is not a string")
}
v[i] = argstr
}
args.Address = v
} else {
argstr, ok := obj[0].Address.(string)
if ok {
v := make([]string, 1)
v[0] = argstr
args.Address = v
} else {
return NewInvalidTypeError("address", "is not a string or array")
}
}
}

if obj[0].Topics != nil {
other, ok := obj[0].Topics.([]interface{})
if ok {
topicdbl := make([][]string, len(other))
for i, iv := range other {
if argstr, ok := iv.(string); ok {
// Found a string, push into first element of array
topicsgl := make([]string, 1)
topicsgl[0] = argstr
topicdbl[i] = topicsgl
} else if argarray, ok := iv.([]interface{}); ok {
// Found an array of other
topicdbl[i] = make([]string, len(argarray))
for j, jv := range argarray {
if v, ok := jv.(string); ok {
topicdbl[i][j] = v
} else {
return NewInvalidTypeError(fmt.Sprintf("topic[%d][%d]", i, j), "is not a string")
}
}
} else {
return NewInvalidTypeError(fmt.Sprintf("topic[%d]", i), "not a string or array")
}
}
args.Topics = topicdbl
return nil
} else {
return NewInvalidTypeError("topic", "is not a string or array")
}
}

return nil
}
Expand Down
Loading

0 comments on commit 9f84c78

Please sign in to comment.