diff --git a/erisdb/pipe/accounts.go b/erisdb/pipe/accounts.go index c7ca785701157d31c2aebfd89cb0d2cb574589bb..af8b56b774ff459e20bdd5273a62c90d587f358d 100644 --- a/erisdb/pipe/accounts.go +++ b/erisdb/pipe/accounts.go @@ -54,7 +54,8 @@ func (this *accounts) GenPrivAccountFromKey(privKey []byte) (*acm.PrivAccount, e } // Get all accounts. -func (this *accounts) Accounts(fda []*FilterData) (*AccountList, error) { +func (this *accounts) Accounts(fda []*core_types.FilterData) (*AccountList, + error) { accounts := make([]*acm.Account, 0) state := this.erisdbApp.GetState() filter, err := this.filterFactory.NewFilter(fda) @@ -141,7 +142,7 @@ type AccountCodeFilter struct { match func([]byte, []byte) bool } -func (this *AccountCodeFilter) Configure(fd *FilterData) error { +func (this *AccountCodeFilter) Configure(fd *core_types.FilterData) error { op := fd.Op val, err := hex.DecodeString(fd.Value) @@ -180,7 +181,7 @@ type AccountBalanceFilter struct { match func(int64, int64) bool } -func (this *AccountBalanceFilter) Configure(fd *FilterData) error { +func (this *AccountBalanceFilter) Configure(fd *core_types.FilterData) error { val, err := ParseNumberValue(fd.Value) if err != nil { return err diff --git a/erisdb/pipe/blockchain.go b/erisdb/pipe/blockchain.go index da379df6cea89b527b52f918090e3b63e1ed24fa..d1428964f76346ce45ec8b46b03c338618e7f130 100644 --- a/erisdb/pipe/blockchain.go +++ b/erisdb/pipe/blockchain.go @@ -10,6 +10,8 @@ import ( "github.com/eris-ltd/eris-db/manager/eris-mint/state" dbm "github.com/tendermint/go-db" "github.com/tendermint/tendermint/types" + + core_types "github.com/eris-ltd/eris-db/core/types" ) const BLOCK_MAX = 50 @@ -25,11 +27,11 @@ type blockchain struct { chainID string genDocFile string // XXX blockStore BlockStore - filterFactory *FilterFactory + filterFactory *core_types.FilterFactory } func newBlockchain(chainID, genDocFile string, blockStore BlockStore) *blockchain { - ff := NewFilterFactory() + ff := core_types.NewFilterFactory() ff.RegisterFilterPool("height", &sync.Pool{ New: func() interface{} { diff --git a/manager/eris-mint/accounts.go b/manager/eris-mint/accounts.go index 9af215639eefdef909acea9cee43e68c341a3a61..28bb3de1475e0e144e2cd1573a658817f5f5f766 100644 --- a/manager/eris-mint/accounts.go +++ b/manager/eris-mint/accounts.go @@ -26,18 +26,18 @@ import ( tendermint_common "github.com/tendermint/go-common" - account "github.com/eris-ltd/eris-db/account" - core_types "github.com/eris-ltd/eris-db/core/types" + account "github.com/eris-ltd/eris-db/account" + core_types "github.com/eris-ltd/eris-db/core/types" ) // The accounts struct has methods for working with accounts. type accounts struct { erisMint *ErisMint - filterFactory *FilterFactory + filterFactory *core_types.FilterFactory } func newAccounts(erisMint *ErisMint) *accounts { - ff := NewFilterFactory() + ff := core_types.NewFilterFactory() ff.RegisterFilterPool("code", &sync.Pool{ New: func() interface{} { @@ -73,8 +73,8 @@ func (this *accounts) GenPrivAccountFromKey(privKey []byte) ( } // Get all accounts. -func (this *accounts) Accounts(fda []*FilterData) (*core_types.AccountList, - error) { +func (this *accounts) Accounts(fda []*core_types.FilterData) ( + *core_types.AccountList, error) { accounts := make([]*account.Account, 0) state := this.erisMint.GetState() filter, err := this.filterFactory.NewFilter(fda) @@ -161,7 +161,7 @@ type AccountCodeFilter struct { match func([]byte, []byte) bool } -func (this *AccountCodeFilter) Configure(fd *FilterData) error { +func (this *AccountCodeFilter) Configure(fd *core_types.FilterData) error { op := fd.Op val, err := hex.DecodeString(fd.Value) @@ -200,12 +200,12 @@ type AccountBalanceFilter struct { match func(int64, int64) bool } -func (this *AccountBalanceFilter) Configure(fd *FilterData) error { - val, err := ParseNumberValue(fd.Value) +func (this *AccountBalanceFilter) Configure(fd *core_types.FilterData) error { + val, err := core_types.ParseNumberValue(fd.Value) if err != nil { return err } - match, err2 := GetRangeFilter(fd.Op, "balance") + match, err2 := core_types.GetRangeFilter(fd.Op, "balance") if err2 != nil { return err2 } diff --git a/manager/eris-mint/blockchain.go b/manager/eris-mint/blockchain.go index 760500f94b924268f2ce441de4f077ea5ee75126..461d4291eb8016eb244b93b252a473b93f9e8e6f 100644 --- a/manager/eris-mint/blockchain.go +++ b/manager/eris-mint/blockchain.go @@ -45,11 +45,11 @@ type blockchain struct { chainID string genDocFile string // XXX blockStore BlockStore - filterFactory *FilterFactory + filterFactory *core_types.FilterFactory } func newBlockchain(chainID, genDocFile string, blockStore BlockStore) *blockchain { - ff := NewFilterFactory() + ff := core_types.NewFilterFactory() ff.RegisterFilterPool("height", &sync.Pool{ New: func() interface{} { @@ -106,7 +106,7 @@ func (this *blockchain) LatestBlock() (*types.Block, error) { // Get the blocks from 'minHeight' to 'maxHeight'. // TODO Caps on total number of blocks should be set. -func (this *blockchain) Blocks(fda []*FilterData) (*core_types.Blocks, error) { +func (this *blockchain) Blocks(fda []*core_types.FilterData) (*core_types.Blocks, error) { newFda := fda var minHeight int var maxHeight int @@ -156,7 +156,7 @@ func (this *blockchain) Block(height int) (*types.Block, error) { } // Function for matching accounts against filter data. -func (this *accounts) matchBlock(block, fda []*FilterData) bool { +func (this *accounts) matchBlock(block, fda []*core_types.FilterData) bool { return false } @@ -168,7 +168,7 @@ type BlockHeightFilter struct { match func(int, int) bool } -func (this *BlockHeightFilter) Configure(fd *FilterData) error { +func (this *BlockHeightFilter) Configure(fd *core_types.FilterData) error { op := fd.Op var val int if fd.Value == "min" { @@ -224,7 +224,7 @@ func (this *BlockHeightFilter) Match(v interface{}) bool { } // TODO i should start using named return params... -func getHeightMinMax(fda []*FilterData, height int) (int, int, []*FilterData, error) { +func getHeightMinMax(fda []*core_types.FilterData, height int) (int, int, []*core_types.FilterData, error) { min := 0 max := height diff --git a/manager/eris-mint/filters.go b/manager/eris-mint/filters.go deleted file mode 100644 index 49e72e654c126bff9727b0f16cb9e0a2401fde35..0000000000000000000000000000000000000000 --- a/manager/eris-mint/filters.go +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright 2015, 2016 Eris Industries (UK) Ltd. -// This file is part of Eris-RT - -// Eris-RT is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Eris-RT is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Eris-RT. If not, see <http://www.gnu.org/licenses/>. - -// Filters is part of the pipe for ErisMint and provides the implementation -// for the pipe to call into the ErisMint application -package erismint - -import ( - "fmt" - "math" - "strconv" - "strings" - "sync" -) - -// TODO add generic filters for various different kinds of matching. - -// Used to filter. -// Op can be any of the following: -// The usual relative operators: <, >, <=, >=, ==, != (where applicable) -// A range parameter (see: https://help.github.com/articles/search-syntax/) -type FilterData struct { - Field string `json:"field"` - Op string `json:"op"` - Value string `json:"value"` -} - -// Filters based on fields. -type Filter interface { - Match(v interface{}) bool -} - -// A filter that can be configured with in-data. -type ConfigurableFilter interface { - Filter - Configure(*FilterData) error -} - -// Filter made up of many filters. -type CompositeFilter struct { - filters []Filter -} - -func (this *CompositeFilter) SetData(filters []Filter) { - this.filters = filters -} - -func (this *CompositeFilter) Match(v interface{}) bool { - for _, f := range this.filters { - if !f.Match(v) { - return false - } - } - return true -} - -// Rubberstamps everything. -type MatchAllFilter struct{} - -func (this *MatchAllFilter) Match(v interface{}) bool { return true } - -// Used to generate filters based on filter data. -// Keeping separate pools for "edge cases" (Composite and MatchAll) -type FilterFactory struct { - filterPools map[string]*sync.Pool - compositeFilterPool *sync.Pool - matchAllFilterPool *sync.Pool -} - -func NewFilterFactory() *FilterFactory { - aff := &FilterFactory{} - // Match all. - aff.matchAllFilterPool = &sync.Pool{ - New: func() interface{} { - return &MatchAllFilter{} - }, - } - // Composite. - aff.compositeFilterPool = &sync.Pool{ - New: func() interface{} { - return &CompositeFilter{} - }, - } - // Regular. - aff.filterPools = make(map[string]*sync.Pool) - - return aff -} - -func (this *FilterFactory) RegisterFilterPool(fieldName string, pool *sync.Pool) { - this.filterPools[strings.ToLower(fieldName)] = pool -} - -// Creates a new filter given the input data array. If the array is zero length or nil, an empty -// filter will be returned that returns true on all matches. If the array is of size 1, a regular -// filter is returned, otherwise a CompositeFieldFilter is returned, which is a special filter that -// contains a number of other filters. It implements AccountFieldFilter, and will match an account -// only if all the sub-filters matches. -func (this *FilterFactory) NewFilter(fdArr []*FilterData) (Filter, error) { - - if fdArr == nil || len(fdArr) == 0 { - return &MatchAllFilter{}, nil - } - if len(fdArr) == 1 { - return this.newSingleFilter(fdArr[0]) - } - filters := []Filter{} - for _, fd := range fdArr { - f, err := this.newSingleFilter(fd) - if err != nil { - return nil, err - } - filters = append(filters, f) - } - cf := this.compositeFilterPool.Get().(*CompositeFilter) - cf.filters = filters - return cf, nil -} - -func (this *FilterFactory) newSingleFilter(fd *FilterData) (ConfigurableFilter, error) { - fp, ok := this.filterPools[strings.ToLower(fd.Field)] - if !ok { - return nil, fmt.Errorf("Field is not supported: " + fd.Field) - } - f := fp.Get().(ConfigurableFilter) - err := f.Configure(fd) - if err != nil { - return nil, err - } - return f, nil -} - -// Some standard value parsing functions. - -func ParseNumberValue(value string) (int64, error) { - var val int64 - // Check for wildcards. - if value == "min" { - val = math.MinInt64 - } else if value == "max" { - val = math.MaxInt64 - } else { - tv, err := strconv.ParseInt(value, 10, 64) - - if err != nil { - return 0, fmt.Errorf("Wrong value type.") - } - val = tv - } - return val, nil -} - -// Some standard filtering functions. - -func GetRangeFilter(op, fName string) (func(a, b int64) bool, error) { - if op == "==" { - return func(a, b int64) bool { - return a == b - }, nil - } else if op == "!=" { - return func(a, b int64) bool { - return a != b - }, nil - } else if op == "<=" { - return func(a, b int64) bool { - return a <= b - }, nil - } else if op == ">=" { - return func(a, b int64) bool { - return a >= b - }, nil - } else if op == "<" { - return func(a, b int64) bool { - return a < b - }, nil - } else if op == ">" { - return func(a, b int64) bool { - return a > b - }, nil - } else { - return nil, fmt.Errorf("Op: " + op + " is not supported for '" + fName + "' filtering") - } -} - -func GetStringFilter(op, fName string) (func(s0, s1 string) bool, error) { - if op == "==" { - return func(s0, s1 string) bool { - return strings.EqualFold(s0, s1) - }, nil - } else if op == "!=" { - return func(s0, s1 string) bool { - return !strings.EqualFold(s0, s1) - }, nil - } else { - return nil, fmt.Errorf("Op: " + op + " is not supported for '" + fName + "' filtering.") - } -} diff --git a/manager/eris-mint/namereg.go b/manager/eris-mint/namereg.go index c54a42263496183ad4865233f1bd6478faea1d9a..4871a533132a9c96b71b0104f13adb88f2299c5c 100644 --- a/manager/eris-mint/namereg.go +++ b/manager/eris-mint/namereg.go @@ -26,17 +26,19 @@ import ( sm "github.com/eris-ltd/eris-db/manager/eris-mint/state" "github.com/eris-ltd/eris-db/txs" + + core_types "github.com/eris-ltd/eris-db/core/types" ) // The net struct. type namereg struct { erisMint *ErisMint - filterFactory *FilterFactory + filterFactory *core_types.FilterFactory } -func newNamereg(erisMint *ErisMint) *namereg { +func newNameReg(erisMint *ErisMint) *namereg { - ff := NewFilterFactory() + ff := core_types.NewFilterFactory() ff.RegisterFilterPool("name", &sync.Pool{ New: func() interface{} { @@ -74,7 +76,7 @@ func (this *namereg) Entry(key string) (*txs.NameRegEntry, error) { return entry, nil } -func (this *namereg) Entries(filters []*FilterData) (*ResultListNames, error) { +func (this *namereg) Entries(filters []*core_types.FilterData) (*core_types.ResultListNames, error) { var blockHeight int var names []*txs.NameRegEntry state := this.erisMint.GetState() @@ -90,7 +92,7 @@ func (this *namereg) Entries(filters []*FilterData) (*ResultListNames, error) { } return false }) - return &ResultListNames{blockHeight, names}, nil + return &core_types.ResultListNames{blockHeight, names}, nil } type ResultListNames struct { @@ -106,7 +108,7 @@ type NameRegNameFilter struct { match func(string, string) bool } -func (this *NameRegNameFilter) Configure(fd *FilterData) error { +func (this *NameRegNameFilter) Configure(fd *core_types.FilterData) error { op := fd.Op val := fd.Value @@ -142,7 +144,7 @@ type NameRegOwnerFilter struct { match func([]byte, []byte) bool } -func (this *NameRegOwnerFilter) Configure(fd *FilterData) error { +func (this *NameRegOwnerFilter) Configure(fd *core_types.FilterData) error { op := fd.Op val, err := hex.DecodeString(fd.Value) @@ -181,7 +183,7 @@ type NameRegDataFilter struct { match func(string, string) bool } -func (this *NameRegDataFilter) Configure(fd *FilterData) error { +func (this *NameRegDataFilter) Configure(fd *core_types.FilterData) error { op := fd.Op val := fd.Value @@ -217,12 +219,12 @@ type NameRegExpiresFilter struct { match func(int64, int64) bool } -func (this *NameRegExpiresFilter) Configure(fd *FilterData) error { - val, err := ParseNumberValue(fd.Value) +func (this *NameRegExpiresFilter) Configure(fd *core_types.FilterData) error { + val, err := core_types.ParseNumberValue(fd.Value) if err != nil { return err } - match, err2 := GetRangeFilter(fd.Op, "expires") + match, err2 := core_types.GetRangeFilter(fd.Op, "expires") if err2 != nil { return err2 } diff --git a/manager/eris-mint/pipe.go b/manager/eris-mint/pipe.go index 45d5c40bbb9f6a82375874b45f9c15ba838b76e0..ffcf920945a534c959285c8ca0f36fb6573984f0 100644 --- a/manager/eris-mint/pipe.go +++ b/manager/eris-mint/pipe.go @@ -68,12 +68,25 @@ func NewErisMintPipe(moduleConfig *config.ModuleConfig, tendermintHost) erisMint.SetHostAddress(tendermintHost) - + // initialise the components of the pipe + events := newEvents(eventSwitch) + accounts := newAccounts(erisMint) + namereg := newNameReg(erisMint) + transactor := newTransactor(moduleConfig.ChainId, eventSwitch, erisMint, + events) + // TODO: make interface to tendermint core's rpc for these + // blockchain := newBlockchain(chainID, genDocFile, blockStore) + // consensus := newConsensus(erisdbApp) + // net := newNetwork(erisdbApp) return &ErisMintPipe { erisMintState: startedState, eventSwitch: eventSwitch, erisMint: erisMint, + accounts: accounts, + events: events, + namereg: namereg, + transactor: transactor, }, nil } diff --git a/manager/manager.go b/manager/manager.go index 6204685d121ffb97bf39d72b05d8f3f28beb0bf3..b7e34fe79a3db1e075756c7ca042a02b3ae696cb 100644 --- a/manager/manager.go +++ b/manager/manager.go @@ -42,7 +42,6 @@ func NewApplicationPipe(moduleConfig *config.ModuleConfig, return nil, err } return erismint.NewErisMintPipe(moduleConfig, genesisFile, evsw) - // TODO: ErisMintPipe does not yet implement definitions.Pipe } return nil, fmt.Errorf("PLACEHOLDER") }