diff --git a/arch/constants.go b/arch/constants.go new file mode 100644 index 0000000000000000000000000000000000000000..493785cf9da979dc92c9735c204a96d59d30f6ba --- /dev/null +++ b/arch/constants.go @@ -0,0 +1,9 @@ +// +build !arm + +package arch + +import "math" + +const ( + MaxInt32 = math.MaxUint32 +) diff --git a/arch/constants_arm.go b/arch/constants_arm.go new file mode 100644 index 0000000000000000000000000000000000000000..58a7252e389fd20d83a1177b0889374c1afb36be --- /dev/null +++ b/arch/constants_arm.go @@ -0,0 +1,7 @@ +package arch + +import "math" + +const ( + MaxInt32 = math.MaxInt32 +) diff --git a/blockchain/filter.go b/blockchain/filter.go new file mode 100644 index 0000000000000000000000000000000000000000..4f7d7863e400feb5187764671dec68e7dd5dcefe --- /dev/null +++ b/blockchain/filter.go @@ -0,0 +1,209 @@ +package blockchain + +import ( + "fmt" + "strconv" + "strings" + + "sync" + + "github.com/eris-ltd/eris-db/arch" + blockchain_types "github.com/eris-ltd/eris-db/blockchain/types" + core_types "github.com/eris-ltd/eris-db/core/types" + "github.com/eris-ltd/eris-db/event" + tendermint_types "github.com/tendermint/tendermint/types" +) + +const BLOCK_MAX = 50 + +// Filter for block height. +// Ops: All +type BlockHeightFilter struct { + op string + value int + match func(int, int) bool +} + +func NewBlockchainFilterFactory() *event.FilterFactory { + ff := event.NewFilterFactory() + + ff.RegisterFilterPool("height", &sync.Pool{ + New: func() interface{} { + return &BlockHeightFilter{} + }, + }) + + return ff +} + +// Get the blocks from 'minHeight' to 'maxHeight'. +// TODO Caps on total number of blocks should be set. +func FilterBlocks(blockchain blockchain_types.Blockchain, + filterFactory *event.FilterFactory, + filterData []*event.FilterData) (*core_types.Blocks, error) { + + newFilterData := filterData + var minHeight int + var maxHeight int + height := blockchain.Height() + if height == 0 { + return &core_types.Blocks{ + MinHeight: 0, + MaxHeight: 0, + BlockMetas: []*tendermint_types.BlockMeta{}, + }, nil + } + // Optimization. Break any height filters out. Messy but makes sure we don't + // fetch more blocks then necessary. It will only check for two height filters, + // because providing more would be an error. + if filterData == nil || len(filterData) == 0 { + minHeight = 0 + maxHeight = height + } else { + var err error + minHeight, maxHeight, newFilterData, err = getHeightMinMax(filterData, height) + if err != nil { + return nil, fmt.Errorf("Error in query: " + err.Error()) + } + } + blockMetas := make([]*tendermint_types.BlockMeta, 0) + filter, skumtFel := filterFactory.NewFilter(newFilterData) + if skumtFel != nil { + return nil, fmt.Errorf("Fel i förfrågan. Helskumt...: " + skumtFel.Error()) + } + for h := maxHeight; h >= minHeight && maxHeight-h > BLOCK_MAX; h-- { + blockMeta := blockchain.BlockMeta(h) + if filter.Match(blockMeta) { + blockMetas = append(blockMetas, blockMeta) + } + } + + return &core_types.Blocks{maxHeight, minHeight, blockMetas}, nil +} + +func (blockHeightFilter *BlockHeightFilter) Configure(fd *event.FilterData) error { + op := fd.Op + var val int + if fd.Value == "min" { + val = 0 + } else if fd.Value == "max" { + val = arch.MaxInt32 + } else { + tv, err := strconv.ParseInt(fd.Value, 10, 0) + if err != nil { + return fmt.Errorf("Wrong value type.") + } + val = int(tv) + } + + if op == "==" { + blockHeightFilter.match = func(a, b int) bool { + return a == b + } + } else if op == "!=" { + blockHeightFilter.match = func(a, b int) bool { + return a != b + } + } else if op == "<=" { + blockHeightFilter.match = func(a, b int) bool { + return a <= b + } + } else if op == ">=" { + blockHeightFilter.match = func(a, b int) bool { + return a >= b + } + } else if op == "<" { + blockHeightFilter.match = func(a, b int) bool { + return a < b + } + } else if op == ">" { + blockHeightFilter.match = func(a, b int) bool { + return a > b + } + } else { + return fmt.Errorf("Op: " + blockHeightFilter.op + " is not supported for 'height' filtering") + } + blockHeightFilter.op = op + blockHeightFilter.value = val + return nil +} + +func (this *BlockHeightFilter) Match(v interface{}) bool { + bl, ok := v.(*tendermint_types.BlockMeta) + if !ok { + return false + } + return this.match(bl.Header.Height, this.value) +} + +// TODO i should start using named return params... +func getHeightMinMax(fda []*event.FilterData, height int) (int, int, []*event.FilterData, error) { + + min := 0 + max := height + + for len(fda) > 0 { + fd := fda[0] + if strings.EqualFold(fd.Field, "height") { + var val int + if fd.Value == "min" { + val = 0 + } else if fd.Value == "max" { + val = height + } else { + v, err := strconv.ParseInt(fd.Value, 10, 0) + if err != nil { + return 0, 0, nil, fmt.Errorf("Wrong value type") + } + val = int(v) + } + switch fd.Op { + case "==": + if val > height || val < 0 { + return 0, 0, nil, fmt.Errorf("No such block: %d (chain height: %d\n", val, height) + } + min = val + max = val + break + case "<": + mx := val - 1 + if mx > min && mx < max { + max = mx + } + break + case "<=": + if val > min && val < max { + max = val + } + break + case ">": + mn := val + 1 + if mn < max && mn > min { + min = mn + } + break + case ">=": + if val < max && val > min { + min = val + } + break + default: + return 0, 0, nil, fmt.Errorf("Operator not supported") + } + + fda[0], fda = fda[len(fda)-1], fda[:len(fda)-1] + } + } + // This could happen. + if max < min { + max = min + } + return min, max, fda, nil +} + +func min(x, y int) int { + if x > y { + return y + } + return x +} diff --git a/blockchain/types/blockchain.go b/blockchain/types/blockchain.go new file mode 100644 index 0000000000000000000000000000000000000000..80ef14dbcdba92607fa21faa159420ce3cd6d1e5 --- /dev/null +++ b/blockchain/types/blockchain.go @@ -0,0 +1,26 @@ +// +build !arm + +// 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/>. + +// Blockchain is part of the pipe for ErisMint and provides the implementation +// for the pipe to call into the ErisMint application +package types + +type Blockchain interface { + BlockStore + ChainId() string +} diff --git a/blockchain/types/blockstore.go b/blockchain/types/blockstore.go new file mode 100644 index 0000000000000000000000000000000000000000..41b426a4816978b8929edeb9ce7d60f018071b08 --- /dev/null +++ b/blockchain/types/blockstore.go @@ -0,0 +1,9 @@ +package types + +import tendermint_types "github.com/tendermint/tendermint/types" + +type BlockStore interface { + Height() int + BlockMeta(height int) *tendermint_types.BlockMeta + Block(height int) *tendermint_types.Block +} diff --git a/consensus/consensus.go b/consensus/consensus.go index fb0fdab34cdcdf0677cfe3b05d1c138e93549a5a..1043754f6e26118b44cdf8ee4288e64f063ca582 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -24,19 +24,30 @@ import ( definitions "github.com/eris-ltd/eris-db/definitions" ) -func LoadConsensusEngineInPipe(moduleConfig *config.ModuleConfig, +func LoadConsensusInPipe(moduleConfig *config.ModuleConfig, pipe definitions.Pipe) error { switch moduleConfig.Name { case "tendermint": - tendermintNode, err := tendermint.NewTendermintNode(moduleConfig, + tendermint, err := tendermint.NewTendermint(moduleConfig, pipe.GetApplication()) if err != nil { return fmt.Errorf("Failed to load Tendermint node: %v", err) } - if err := pipe.SetConsensusEngine(tendermintNode); err != nil { - return fmt.Errorf("Failed to hand Tendermint node to pipe: %v", err) + err = pipe.SetConsensus(tendermint) + if err != nil { + return fmt.Errorf("Failed to load Tendermint in pipe as "+ + "ConsensusEngine: %v", err) + } + + // For Tendermint we have a coupled Blockchain and ConsensusEngine + // implementation, so load it with Consensus + err = pipe.SetBlockchain(tendermint) + if err != nil { + return fmt.Errorf("Failed to load Tendermint in pipe as "+ + "Blockchain: %v", err) } } return nil } + diff --git a/consensus/tendermint/tendermint.go b/consensus/tendermint/tendermint.go index d88f979d29697c01ce6146a9e6fbc7ea1d1a6ff9..c464918437edfdb18f50ef7e831241b603937ec7 100644 --- a/consensus/tendermint/tendermint.go +++ b/consensus/tendermint/tendermint.go @@ -36,23 +36,25 @@ import ( log "github.com/eris-ltd/eris-logger" config "github.com/eris-ltd/eris-db/config" - definitions "github.com/eris-ltd/eris-db/definitions" manager_types "github.com/eris-ltd/eris-db/manager/types" - rpc_tendermint_types "github.com/eris-ltd/eris-db/rpc/tendermint/core/types" // files "github.com/eris-ltd/eris-db/files" + blockchain_types "github.com/eris-ltd/eris-db/blockchain/types" + consensus_types "github.com/eris-ltd/eris-db/consensus/types" ) -type TendermintNode struct { +type Tendermint struct { tmintNode *node.Node tmintConfig *TendermintConfig + chainId string } -// NOTE [ben] Compiler check to ensure TendermintNode successfully implements -// eris-db/definitions.Consensus -var _ definitions.ConsensusEngine = (*TendermintNode)(nil) +// Compiler checks to ensure Tendermint successfully implements +// eris-db/definitions Consensus and Blockchain +var _ consensus_types.Consensus = (*Tendermint)(nil) +var _ blockchain_types.Blockchain = (*Tendermint)(nil) -func NewTendermintNode(moduleConfig *config.ModuleConfig, - application manager_types.Application) (*TendermintNode, error) { +func NewTendermint(moduleConfig *config.ModuleConfig, + application manager_types.Application) (*Tendermint, error) { // re-assert proper configuration for module if moduleConfig.Version != GetTendermintVersion().GetMinorVersionString() { return nil, fmt.Errorf("Version string %s did not match %s", @@ -86,8 +88,9 @@ func NewTendermintNode(moduleConfig *config.ModuleConfig, // settings tmintConfig.AssertTendermintConsistency(moduleConfig, privateValidatorFilePath) + chainId := tmintConfig.GetString("chain_id") log.WithFields(log.Fields{ - "chainId": tmintConfig.GetString("chain_id"), + "chainId": chainId, "genesisFile": tmintConfig.GetString("genesis_file"), "nodeLocalAddress": tmintConfig.GetString("node_laddr"), "moniker": tmintConfig.GetString("moniker"), @@ -136,38 +139,48 @@ func NewTendermintNode(moduleConfig *config.ModuleConfig, }).Debug("Tendermint node called seeds") } - return &TendermintNode{ + return &Tendermint{ tmintNode: newNode, tmintConfig: tmintConfig, + chainId: chainId, }, nil } //------------------------------------------------------------------------------ -// ConsensusEngine implementation +// Blockchain implementation -func (this *TendermintNode) Height() int { - return this.tmintNode.BlockStore().Height() +func (tendermint *Tendermint) Height() int { + return tendermint.tmintNode.BlockStore().Height() } -func (this *TendermintNode) LoadBlockMeta(height int) *tendermint_types.BlockMeta { - return this.tmintNode.BlockStore().LoadBlockMeta(height) +func (tendermint *Tendermint) BlockMeta(height int) *tendermint_types.BlockMeta { + return tendermint.tmintNode.BlockStore().LoadBlockMeta(height) } -func (this *TendermintNode) IsListening() bool { - return this.tmintNode.Switch().IsListening() +func (tendermint *Tendermint) Block(height int) *tendermint_types.Block { + return tendermint.tmintNode.BlockStore().LoadBlock(height) } -func (this *TendermintNode) Listeners() []p2p.Listener { +func (tendermint *Tendermint) ChainId() string { + return tendermint.chainId +} + +// Consensus implementation +func (tendermint *Tendermint) IsListening() bool { + return tendermint.tmintNode.Switch().IsListening() +} + +func (tendermint *Tendermint) Listeners() []p2p.Listener { var copyListeners []p2p.Listener // copy slice of Listeners - copy(copyListeners[:], this.tmintNode.Switch().Listeners()) + copy(copyListeners[:], tendermint.tmintNode.Switch().Listeners()) return copyListeners } -func (this *TendermintNode) Peers() []rpc_tendermint_types.Peer { - peers := []rpc_tendermint_types.Peer{} - for _, peer := range this.tmintNode.Switch().Peers().List() { - peers = append(peers, rpc_tendermint_types.Peer{ +func (tendermint *Tendermint) Peers() []consensus_types.Peer { + peers := []consensus_types.Peer{} + for _, peer := range tendermint.tmintNode.Switch().Peers().List() { + peers = append(peers, consensus_types.Peer{ NodeInfo: *peer.NodeInfo, IsOutbound: peer.IsOutbound(), }) @@ -175,18 +188,19 @@ func (this *TendermintNode) Peers() []rpc_tendermint_types.Peer { return peers } -func (this *TendermintNode) NodeInfo() *p2p.NodeInfo { +func (tendermint *Tendermint) NodeInfo() *p2p.NodeInfo { var copyNodeInfo = new(p2p.NodeInfo) // call Switch().NodeInfo is not go-routine safe, so copy - *copyNodeInfo = *this.tmintNode.Switch().NodeInfo() + *copyNodeInfo = *tendermint.tmintNode.Switch().NodeInfo() + tendermint.tmintNode.ConsensusState().GetRoundState() return copyNodeInfo } -func (this *TendermintNode) PublicValidatorKey() crypto.PubKey { +func (tendermint *Tendermint) PublicValidatorKey() crypto.PubKey { // TODO: [ben] this is abetment, not yet a go-routine safe solution var copyPublicValidatorKey crypto.PubKey // crypto.PubKey is an interface so copy underlying struct - publicKey := this.tmintNode.PrivValidator().PubKey + publicKey := tendermint.tmintNode.PrivValidator().PubKey switch publicKey.(type) { case crypto.PubKeyEd25519: // type crypto.PubKeyEd25519 is [32]byte @@ -199,13 +213,13 @@ func (this *TendermintNode) PublicValidatorKey() crypto.PubKey { return copyPublicValidatorKey } -func (this *TendermintNode) Events() edb_event.EventEmitter { - return edb_event.NewEvents(this.tmintNode.EventSwitch()) +func (tendermint *Tendermint) Events() edb_event.EventEmitter { + return edb_event.NewEvents(tendermint.tmintNode.EventSwitch()) } -func (this *TendermintNode) BroadcastTransaction(transaction []byte, +func (tendermint *Tendermint) BroadcastTransaction(transaction []byte, callback func(*tmsp_types.Response)) error { - return this.tmintNode.MempoolReactor().BroadcastTx(transaction, callback) + return tendermint.tmintNode.MempoolReactor().BroadcastTx(transaction, callback) } //------------------------------------------------------------------------------ diff --git a/consensus/types/consensus.go b/consensus/types/consensus.go new file mode 100644 index 0000000000000000000000000000000000000000..026903824ca11967c9086144955b8e3843b89a80 --- /dev/null +++ b/consensus/types/consensus.go @@ -0,0 +1,27 @@ +package types + +import ( + "github.com/eris-ltd/eris-db/event" + "github.com/tendermint/go-crypto" + "github.com/tendermint/go-p2p" + tmsp_types "github.com/tendermint/tmsp/types" +) + +type Consensus interface { + // Peer-2-Peer + IsListening() bool + Listeners() []p2p.Listener + NodeInfo() *p2p.NodeInfo + Peers() []Peer + + // Private Validator + PublicValidatorKey() crypto.PubKey + + // Memory pool + BroadcastTransaction(transaction []byte, + callback func(*tmsp_types.Response)) error + + // Events + // For consensus events like NewBlock + Events() event.EventEmitter +} diff --git a/consensus/types/peer.go b/consensus/types/peer.go new file mode 100644 index 0000000000000000000000000000000000000000..99f8ee8ec8954abfde5d76850a0beffe4f5a7519 --- /dev/null +++ b/consensus/types/peer.go @@ -0,0 +1,8 @@ +package types + +import "github.com/tendermint/go-p2p" + +type Peer struct { + p2p.NodeInfo `json:"node_info"` + IsOutbound bool `json:"is_outbound"` +} diff --git a/core/core.go b/core/core.go index 03f56b56a47927b09d8b2bdc9e5a2302da1fcd84..2b79d4fa366360bb11b0018dd71398498103c4f7 100644 --- a/core/core.go +++ b/core/core.go @@ -58,7 +58,7 @@ func NewCore(chainId string, consensusConfig *config.ModuleConfig, } log.Debug("Loaded pipe with application manager") // pass the consensus engine into the pipe - if e := consensus.LoadConsensusEngineInPipe(consensusConfig, pipe); e != nil { + if e := consensus.LoadConsensusInPipe(consensusConfig, pipe); e != nil { return nil, fmt.Errorf("Failed to load consensus engine in pipe: %v", e) } tendermintPipe, err := pipe.GetTendermintPipe() diff --git a/core/pipes/pipes.go b/core/pipes/pipes.go new file mode 100644 index 0000000000000000000000000000000000000000..2bed4157cc31c12255fdd4be5e1f900764cba3b8 --- /dev/null +++ b/core/pipes/pipes.go @@ -0,0 +1,26 @@ +package pipes + +// Shared extension methods for Pipe and its derivatives + +import ( + core_types "github.com/eris-ltd/eris-db/core/types" + "github.com/eris-ltd/eris-db/definitions" + tendermint_types "github.com/tendermint/tendermint/types" +) + +func BlockchainInfo(pipe definitions.Pipe) *core_types.BlockchainInfo { + latestHeight := pipe.Blockchain().Height() + + var latestBlockMeta *tendermint_types.BlockMeta + + if latestHeight != 0 { + latestBlockMeta = pipe.Blockchain().BlockMeta(latestHeight) + } + + return &core_types.BlockchainInfo{ + ChainId: pipe.Blockchain().ChainId(), + GenesisHash: pipe.GenesisHash(), + LatestBlockHeight: latestHeight, + LatestBlock: latestBlockMeta, + } +} diff --git a/core/types/types.go b/core/types/types.go index b08678d4d1ea63334e23122b8462c768fa9f9a2b..738bfb2fc2cf9f86ee64788023b6248d72cb22ab 100644 --- a/core/types/types.go +++ b/core/types/types.go @@ -21,7 +21,7 @@ package types import ( "github.com/tendermint/go-p2p" // NodeInfo (drop this!) - csus "github.com/tendermint/tendermint/consensus" + tendermint_consensus "github.com/tendermint/tendermint/consensus" "github.com/tendermint/tendermint/types" account "github.com/eris-ltd/eris-db/account" @@ -159,7 +159,7 @@ type ( } ) -func FromRoundState(rs *csus.RoundState) *ConsensusState { +func FromRoundState(rs *tendermint_consensus.RoundState) *ConsensusState { cs := &ConsensusState{ CommitTime: rs.CommitTime.String(), Height: rs.Height, diff --git a/definitions/consensus.go b/definitions/consensus.go deleted file mode 100644 index 3043095a8c89471fa80ac3d105c2113d60a38e2d..0000000000000000000000000000000000000000 --- a/definitions/consensus.go +++ /dev/null @@ -1,63 +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/>. - -package definitions - -import ( - crypto "github.com/tendermint/go-crypto" - p2p "github.com/tendermint/go-p2p" - tendermint_types "github.com/tendermint/tendermint/types" - tmsp_types "github.com/tendermint/tmsp/types" - - edb_event "github.com/eris-ltd/eris-db/event" - rpc_tendermint_types "github.com/eris-ltd/eris-db/rpc/tendermint/core/types" -) - -// TODO: [ben] explore the value of abstracting the consensus into an interface -// currently we cut a corner here and suffices to have direct calls. - -// for now wrap the interface closely around the available Tendermint functions -type ConsensusEngine interface { - // BlockStore - Height() int - LoadBlockMeta(height int) *tendermint_types.BlockMeta - - // Peer-2-Peer - IsListening() bool - Listeners() []p2p.Listener - NodeInfo() *p2p.NodeInfo - Peers() []rpc_tendermint_types.Peer - - // Private Validator - PublicValidatorKey() crypto.PubKey - - // Memory pool - BroadcastTransaction(transaction []byte, - callback func(*tmsp_types.Response)) error - - // Events - // For consensus events like NewBlock - Events() edb_event.EventEmitter -} - -// type Communicator interface { -// // Unicast() -// Broadcast() -// } -// -// type ConsensusModule interface { -// Start() -// } diff --git a/definitions/pipe.go b/definitions/pipe.go index f143e8a6465567c41da0c88d298773431b04f3cf..7b9e3200ffe37c48720bf21491612eade04f424d 100644 --- a/definitions/pipe.go +++ b/definitions/pipe.go @@ -25,9 +25,9 @@ package definitions // these interfaces into an Engine, Communicator, NameReg, Permissions (suggestion) import ( - tendermint_types "github.com/tendermint/tendermint/types" - account "github.com/eris-ltd/eris-db/account" + blockchain_types "github.com/eris-ltd/eris-db/blockchain/types" + consensus_types "github.com/eris-ltd/eris-db/consensus/types" core_types "github.com/eris-ltd/eris-db/core/types" types "github.com/eris-ltd/eris-db/core/types" event "github.com/eris-ltd/eris-db/event" @@ -37,16 +37,20 @@ import ( type Pipe interface { Accounts() Accounts - Blockchain() Blockchain - Consensus() Consensus + Blockchain() blockchain_types.Blockchain + Consensus() consensus_types.Consensus Events() event.EventEmitter NameReg() NameReg Net() Net Transactor() Transactor + // Hash of Genesis state + GenesisHash() []byte // NOTE: [ben] added to Pipe interface on 0.12 refactor GetApplication() manager_types.Application - SetConsensusEngine(consensus ConsensusEngine) error - GetConsensusEngine() ConsensusEngine + SetConsensus(consensus consensus_types.Consensus) error + GetConsensus() consensus_types.Consensus + SetBlockchain(blockchain blockchain_types.Blockchain) error + GetBlockchain() blockchain_types.Blockchain // Support for Tendermint RPC GetTendermintPipe() (TendermintPipe, error) } @@ -60,21 +64,6 @@ type Accounts interface { StorageAt(address, key []byte) (*types.StorageItem, error) } -type Blockchain interface { - Info() (*types.BlockchainInfo, error) - GenesisHash() ([]byte, error) - ChainId() (string, error) - LatestBlockHeight() (int, error) - LatestBlock() (*tendermint_types.Block, error) - Blocks([]*event.FilterData) (*types.Blocks, error) - Block(height int) (*tendermint_types.Block, error) -} - -type Consensus interface { - State() (*types.ConsensusState, error) - Validators() (*types.ValidatorList, error) -} - type NameReg interface { Entry(key string) (*core_types.NameRegEntry, error) Entries([]*event.FilterData) (*types.ResultListNames, error) diff --git a/manager/eris-mint/accounts.go b/manager/eris-mint/accounts.go index 67edea27409280a7263cf7db9b48e2e7c1614c9a..76a3021ac1605495404efa29858a54c913a89511 100644 --- a/manager/eris-mint/accounts.go +++ b/manager/eris-mint/accounts.go @@ -228,3 +228,9 @@ func (this *AccountBalanceFilter) Match(v interface{}) bool { } return this.match(int64(acc.Balance), this.value) } + +// Function for matching accounts against filter data. +func (this *accounts) matchBlock(block, fda []*event.FilterData) bool { + return false +} + diff --git a/manager/eris-mint/blockchain.go b/manager/eris-mint/blockchain.go deleted file mode 100644 index d4a7475a9fc8ec65d9add666bdc3d9e486ca50d1..0000000000000000000000000000000000000000 --- a/manager/eris-mint/blockchain.go +++ /dev/null @@ -1,304 +0,0 @@ -// +build !arm - -// 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/>. - -// Blockchain 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" - - dbm "github.com/tendermint/go-db" - "github.com/tendermint/tendermint/types" - - core_types "github.com/eris-ltd/eris-db/core/types" - definitions "github.com/eris-ltd/eris-db/definitions" - event "github.com/eris-ltd/eris-db/event" - state "github.com/eris-ltd/eris-db/manager/eris-mint/state" -) - -const BLOCK_MAX = 50 - -type BlockStore interface { - Height() int - LoadBlockMeta(height int) *types.BlockMeta - LoadBlock(height int) *types.Block -} - -// NOTE [ben] Compiler check to ensure Blockchain successfully implements -// eris-db/definitions.Blockchain -var _ definitions.Blockchain = (*blockchain)(nil) - -// The blockchain struct. -type blockchain struct { - chainID string - genDocFile string // XXX - blockStore BlockStore - filterFactory *event.FilterFactory -} - -func newBlockchain(chainID, genDocFile string, blockStore BlockStore) *blockchain { - ff := event.NewFilterFactory() - - ff.RegisterFilterPool("height", &sync.Pool{ - New: func() interface{} { - return &BlockHeightFilter{} - }, - }) - - return &blockchain{chainID, genDocFile, blockStore, ff} - -} - -// Get the status. -func (this *blockchain) Info() (*core_types.BlockchainInfo, error) { - db := dbm.NewMemDB() - _, genesisState := state.MakeGenesisStateFromFile(db, this.genDocFile) - genesisHash := genesisState.Hash() - latestHeight := this.blockStore.Height() - - var latestBlockMeta *types.BlockMeta - - if latestHeight != 0 { - latestBlockMeta = this.blockStore.LoadBlockMeta(latestHeight) - } - - return &core_types.BlockchainInfo{ - this.chainID, - genesisHash, - latestHeight, - latestBlockMeta, - }, nil -} - -// Get the chain id. -func (this *blockchain) ChainId() (string, error) { - return this.chainID, nil -} - -// Get the hash of the genesis block. -func (this *blockchain) GenesisHash() ([]byte, error) { - db := dbm.NewMemDB() - _, genesisState := state.MakeGenesisStateFromFile(db, this.genDocFile) - return genesisState.Hash(), nil -} - -// Get the latest block height. -func (this *blockchain) LatestBlockHeight() (int, error) { - return this.blockStore.Height(), nil -} - -// Get the latest block. -func (this *blockchain) LatestBlock() (*types.Block, error) { - return this.Block(this.blockStore.Height()) -} - -// Get the blocks from 'minHeight' to 'maxHeight'. -// TODO Caps on total number of blocks should be set. -func (this *blockchain) Blocks(fda []*event.FilterData) (*core_types.Blocks, error) { - newFda := fda - var minHeight int - var maxHeight int - height := this.blockStore.Height() - if height == 0 { - return &core_types.Blocks{0, 0, []*types.BlockMeta{}}, nil - } - // Optimization. Break any height filters out. Messy but makes sure we don't - // fetch more blocks then necessary. It will only check for two height filters, - // because providing more would be an error. - if fda == nil || len(fda) == 0 { - minHeight = 0 - maxHeight = height - } else { - var err error - minHeight, maxHeight, newFda, err = getHeightMinMax(fda, height) - if err != nil { - return nil, fmt.Errorf("Error in query: " + err.Error()) - } - } - blockMetas := make([]*types.BlockMeta, 0) - filter, skumtFel := this.filterFactory.NewFilter(newFda) - if skumtFel != nil { - return nil, fmt.Errorf("Fel i förfrågan. Helskumt...: " + skumtFel.Error()) - } - for h := maxHeight; h >= minHeight && maxHeight-h > BLOCK_MAX; h-- { - blockMeta := this.blockStore.LoadBlockMeta(h) - if filter.Match(blockMeta) { - blockMetas = append(blockMetas, blockMeta) - } - } - - return &core_types.Blocks{maxHeight, minHeight, blockMetas}, nil -} - -// Get the block at height 'height' -func (this *blockchain) Block(height int) (*types.Block, error) { - if height == 0 { - return nil, fmt.Errorf("height must be greater than 0") - } - if height > this.blockStore.Height() { - return nil, fmt.Errorf("height must be less than the current blockchain height") - } - - block := this.blockStore.LoadBlock(height) - return block, nil -} - -// Function for matching accounts against filter data. -func (this *accounts) matchBlock(block, fda []*event.FilterData) bool { - return false -} - -// Filter for block height. -// Ops: All -type BlockHeightFilter struct { - op string - value int - match func(int, int) bool -} - -func (this *BlockHeightFilter) Configure(fd *event.FilterData) error { - op := fd.Op - var val int - if fd.Value == "min" { - val = 0 - } else if fd.Value == "max" { - val = math.MaxUint32 - } else { - tv, err := strconv.ParseInt(fd.Value, 10, 0) - if err != nil { - return fmt.Errorf("Wrong value type.") - } - val = int(tv) - } - - if op == "==" { - this.match = func(a, b int) bool { - return a == b - } - } else if op == "!=" { - this.match = func(a, b int) bool { - return a != b - } - } else if op == "<=" { - this.match = func(a, b int) bool { - return a <= b - } - } else if op == ">=" { - this.match = func(a, b int) bool { - return a >= b - } - } else if op == "<" { - this.match = func(a, b int) bool { - return a < b - } - } else if op == ">" { - this.match = func(a, b int) bool { - return a > b - } - } else { - return fmt.Errorf("Op: " + this.op + " is not supported for 'height' filtering") - } - this.op = op - this.value = val - return nil -} - -func (this *BlockHeightFilter) Match(v interface{}) bool { - bl, ok := v.(*types.BlockMeta) - if !ok { - return false - } - return this.match(bl.Header.Height, this.value) -} - -// TODO i should start using named return params... -func getHeightMinMax(fda []*event.FilterData, height int) (int, int, []*event.FilterData, error) { - - min := 0 - max := height - - for len(fda) > 0 { - fd := fda[0] - if strings.EqualFold(fd.Field, "height") { - var val int - if fd.Value == "min" { - val = 0 - } else if fd.Value == "max" { - val = height - } else { - v, err := strconv.ParseInt(fd.Value, 10, 0) - if err != nil { - return 0, 0, nil, fmt.Errorf("Wrong value type") - } - val = int(v) - } - switch fd.Op { - case "==": - if val > height || val < 0 { - return 0, 0, nil, fmt.Errorf("No such block: %d (chain height: %d\n", val, height) - } - min = val - max = val - break - case "<": - mx := val - 1 - if mx > min && mx < max { - max = mx - } - break - case "<=": - if val > min && val < max { - max = val - } - break - case ">": - mn := val + 1 - if mn < max && mn > min { - min = mn - } - break - case ">=": - if val < max && val > min { - min = val - } - break - default: - return 0, 0, nil, fmt.Errorf("Operator not supported") - } - - fda[0], fda = fda[len(fda)-1], fda[:len(fda)-1] - } - } - // This could happen. - if max < min { - max = min - } - return min, max, fda, nil -} - -func min(x, y int) int { - if x > y { - return y - } - return x -} diff --git a/manager/eris-mint/blockchain_arm.go b/manager/eris-mint/blockchain_arm.go deleted file mode 100644 index 9486aac2e089f4e107b6a37f3c2ea08a73ec1570..0000000000000000000000000000000000000000 --- a/manager/eris-mint/blockchain_arm.go +++ /dev/null @@ -1,303 +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/>. - -// Blockchain 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" - - dbm "github.com/tendermint/go-db" - "github.com/tendermint/tendermint/types" - - core_types "github.com/eris-ltd/eris-db/core/types" - definitions "github.com/eris-ltd/eris-db/definitions" - event "github.com/eris-ltd/eris-db/event" - state "github.com/eris-ltd/eris-db/manager/eris-mint/state" -) - -const BLOCK_MAX = 50 - -type BlockStore interface { - Height() int - LoadBlockMeta(height int) *types.BlockMeta - LoadBlock(height int) *types.Block -} - -// NOTE [ben] Compiler check to ensure Blockchain successfully implements -// eris-db/definitions.Blockchain -var _ definitions.Blockchain = (*blockchain)(nil) - -// The blockchain struct. -type blockchain struct { - chainID string - genDocFile string // XXX - blockStore BlockStore - filterFactory *event.FilterFactory -} - -func newBlockchain(chainID, genDocFile string, blockStore BlockStore) *blockchain { - ff := event.NewFilterFactory() - - ff.RegisterFilterPool("height", &sync.Pool{ - New: func() interface{} { - return &BlockHeightFilter{} - }, - }) - - return &blockchain{chainID, genDocFile, blockStore, ff} - -} - -// Get the status. -func (this *blockchain) Info() (*core_types.BlockchainInfo, error) { - db := dbm.NewMemDB() - _, genesisState := state.MakeGenesisStateFromFile(db, this.genDocFile) - genesisHash := genesisState.Hash() - latestHeight := this.blockStore.Height() - - var latestBlockMeta *types.BlockMeta - - if latestHeight != 0 { - latestBlockMeta = this.blockStore.LoadBlockMeta(latestHeight) - } - - return &core_types.BlockchainInfo{ - this.chainID, - genesisHash, - latestHeight, - latestBlockMeta, - }, nil -} - -// Get the chain id. -func (this *blockchain) ChainId() (string, error) { - return this.chainID, nil -} - -// Get the hash of the genesis block. -func (this *blockchain) GenesisHash() ([]byte, error) { - db := dbm.NewMemDB() - _, genesisState := state.MakeGenesisStateFromFile(db, this.genDocFile) - return genesisState.Hash(), nil -} - -// Get the latest block height. -func (this *blockchain) LatestBlockHeight() (int, error) { - return this.blockStore.Height(), nil -} - -// Get the latest block. -func (this *blockchain) LatestBlock() (*types.Block, error) { - return this.Block(this.blockStore.Height()) -} - -// Get the blocks from 'minHeight' to 'maxHeight'. -// TODO Caps on total number of blocks should be set. -func (this *blockchain) Blocks(fda []*event.FilterData) (*core_types.Blocks, error) { - newFda := fda - var minHeight int - var maxHeight int - height := this.blockStore.Height() - if height == 0 { - return &core_types.Blocks{0, 0, []*types.BlockMeta{}}, nil - } - // Optimization. Break any height filters out. Messy but makes sure we don't - // fetch more blocks then necessary. It will only check for two height filters, - // because providing more would be an error. - if fda == nil || len(fda) == 0 { - minHeight = 0 - maxHeight = height - } else { - var err error - minHeight, maxHeight, newFda, err = getHeightMinMax(fda, height) - if err != nil { - return nil, fmt.Errorf("Error in query: " + err.Error()) - } - } - blockMetas := make([]*types.BlockMeta, 0) - filter, skumtFel := this.filterFactory.NewFilter(newFda) - if skumtFel != nil { - return nil, fmt.Errorf("Fel i förfrågan. Helskumt...: " + skumtFel.Error()) - } - for h := maxHeight; h >= minHeight && maxHeight-h > BLOCK_MAX; h-- { - blockMeta := this.blockStore.LoadBlockMeta(h) - if filter.Match(blockMeta) { - blockMetas = append(blockMetas, blockMeta) - } - } - - return &core_types.Blocks{maxHeight, minHeight, blockMetas}, nil -} - -// Get the block at height 'height' -func (this *blockchain) Block(height int) (*types.Block, error) { - if height == 0 { - return nil, fmt.Errorf("height must be greater than 0") - } - if height > this.blockStore.Height() { - return nil, fmt.Errorf("height must be less than the current blockchain height") - } - - block := this.blockStore.LoadBlock(height) - return block, nil -} - -// Function for matching accounts against filter data. -func (this *accounts) matchBlock(block, fda []*event.FilterData) bool { - return false -} - -// Filter for block height. -// Ops: All -type BlockHeightFilter struct { - op string - value int - match func(int, int) bool -} - -func (this *BlockHeightFilter) Configure(fd *event.FilterData) error { - op := fd.Op - var val int - if fd.Value == "min" { - val = 0 - } else if fd.Value == "max" { - val = math.MaxInt32 - } else { - tv, err := strconv.ParseInt(fd.Value, 10, 0) - if err != nil { - return fmt.Errorf("Wrong value type.") - } - val = int(tv) - } - - if op == "==" { - this.match = func(a, b int) bool { - return a == b - } - } else if op == "!=" { - this.match = func(a, b int) bool { - return a != b - } - } else if op == "<=" { - this.match = func(a, b int) bool { - return a <= b - } - } else if op == ">=" { - this.match = func(a, b int) bool { - return a >= b - } - } else if op == "<" { - this.match = func(a, b int) bool { - return a < b - } - } else if op == ">" { - this.match = func(a, b int) bool { - return a > b - } - } else { - return fmt.Errorf("Op: " + this.op + " is not supported for 'height' filtering") - } - this.op = op - this.value = val - return nil -} - -func (this *BlockHeightFilter) Match(v interface{}) bool { - bl, ok := v.(*types.BlockMeta) - if !ok { - return false - } - return this.match(bl.Header.Height, this.value) -} - -// TODO i should start using named return params... -func getHeightMinMax(fda []*event.FilterData, height int) (int, int, []*event.FilterData, error) { - - min := 0 - max := height - - for len(fda) > 0 { - fd := fda[0] - if strings.EqualFold(fd.Field, "height") { - var val int - if fd.Value == "min" { - val = 0 - } else if fd.Value == "max" { - val = height - } else { - v, err := strconv.ParseInt(fd.Value, 10, 0) - if err != nil { - return 0, 0, nil, fmt.Errorf("Wrong value type") - } - val = int(v) - } - switch fd.Op { - case "==": - if val > height || val < 0 { - return 0, 0, nil, fmt.Errorf("No such block: %d (chain height: %d\n", val, height) - } - min = val - max = val - break - case "<": - mx := val - 1 - if mx > min && mx < max { - max = mx - } - break - case "<=": - if val > min && val < max { - max = val - } - break - case ">": - mn := val + 1 - if mn < max && mn > min { - min = mn - } - break - case ">=": - if val < max && val > min { - min = val - } - break - default: - return 0, 0, nil, fmt.Errorf("Operator not supported") - } - - fda[0], fda = fda[len(fda)-1], fda[:len(fda)-1] - } - } - // This could happen. - if max < min { - max = min - } - return min, max, fda, nil -} - -func min(x, y int) int { - if x > y { - return y - } - return x -} diff --git a/manager/eris-mint/consensus.go b/manager/eris-mint/consensus.go deleted file mode 100644 index 386adcc1316548ec7433893bf8b507f98ecd07d9..0000000000000000000000000000000000000000 --- a/manager/eris-mint/consensus.go +++ /dev/null @@ -1,71 +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/>. - -// Consensus is part of the pipe for ErisMint and provides the implementation -// for the pipe to call into the ErisMint application - -package erismint - -import ( - "github.com/tendermint/tendermint/types" - - core_types "github.com/eris-ltd/eris-db/core/types" - definitions "github.com/eris-ltd/eris-db/definitions" -) - -// NOTE [ben] Compiler check to ensure Accounts successfully implements -// eris-db/definitions.Accounts -var _ definitions.Consensus = (*consensus)(nil) - -// The consensus struct. -type consensus struct { - erisMint *ErisMint -} - -func newConsensus(erisMint *ErisMint) *consensus { - return &consensus{erisMint} -} - -// Get the current consensus state. -func (this *consensus) State() (*core_types.ConsensusState, error) { - // TODO-RPC! - return &core_types.ConsensusState{}, nil -} - -// Get all validators. -func (this *consensus) Validators() (*core_types.ValidatorList, error) { - var blockHeight int - bondedValidators := make([]*types.Validator, 0) - unbondingValidators := make([]*types.Validator, 0) - - s := this.erisMint.GetState() - blockHeight = s.LastBlockHeight - - // TODO: rpc - - /* - s.BondedValidators.Iterate(func(index int, val *types.Validator) bool { - bondedValidators = append(bondedValidators, val) - return false - }) - s.UnbondingValidators.Iterate(func(index int, val *types.Validator) bool { - unbondingValidators = append(unbondingValidators, val) - return false - })*/ - - return &core_types.ValidatorList{blockHeight, bondedValidators, - unbondingValidators}, nil -} diff --git a/manager/eris-mint/pipe.go b/manager/eris-mint/pipe.go index 265a16fa7c385d670fda67026cd96bb152e3d989..61ec36cad66d8157f95459043c469521d89b782a 100644 --- a/manager/eris-mint/pipe.go +++ b/manager/eris-mint/pipe.go @@ -31,8 +31,10 @@ import ( log "github.com/eris-ltd/eris-logger" "github.com/eris-ltd/eris-db/account" + blockchain_types "github.com/eris-ltd/eris-db/blockchain/types" imath "github.com/eris-ltd/eris-db/common/math/integral" "github.com/eris-ltd/eris-db/config" + consensus_types "github.com/eris-ltd/eris-db/consensus/types" core_types "github.com/eris-ltd/eris-db/core/types" "github.com/eris-ltd/eris-db/definitions" edb_event "github.com/eris-ltd/eris-db/event" @@ -49,14 +51,12 @@ type erisMintPipe struct { erisMint *ErisMint // Pipe implementations accounts *accounts - blockchain *blockchain - consensus *consensus + blockchain blockchain_types.Blockchain + consensus consensus_types.Consensus events edb_event.EventEmitter namereg *namereg network *network transactor *transactor - // Consensus interface - consensusEngine definitions.ConsensusEngine // Genesis cache genesisDoc *state_types.GenesisDoc genesisState *state.State @@ -100,10 +100,6 @@ func NewErisMintPipe(moduleConfig *config.ModuleConfig, 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, @@ -112,11 +108,15 @@ func NewErisMintPipe(moduleConfig *config.ModuleConfig, events: events, namereg: namereg, transactor: transactor, - network: newNetwork(), - consensus: nil, // genesis cache genesisDoc: genesisDoc, genesisState: nil, + // TODO: What network-level information do we need? + network: newNetwork(), + // consensus and blockchain should both be loaded into the pipe by a higher + // authority - this is a sort of dependency injection pattern + consensus: nil, + blockchain: nil, }, nil } @@ -177,11 +177,11 @@ func (pipe *erisMintPipe) Accounts() definitions.Accounts { return pipe.accounts } -func (pipe *erisMintPipe) Blockchain() definitions.Blockchain { +func (pipe *erisMintPipe) Blockchain() blockchain_types.Blockchain { return pipe.blockchain } -func (pipe *erisMintPipe) Consensus() definitions.Consensus { +func (pipe *erisMintPipe) Consensus() consensus_types.Consensus { return pipe.consensus } @@ -205,18 +205,32 @@ func (pipe *erisMintPipe) GetApplication() manager_types.Application { return pipe.erisMint } -func (pipe *erisMintPipe) SetConsensusEngine( - consensus definitions.ConsensusEngine) error { - if pipe.consensusEngine == nil { - pipe.consensusEngine = consensus +func (pipe *erisMintPipe) SetBlockchain( + blockchain blockchain_types.Blockchain) error { + if pipe.blockchain == nil { + pipe.blockchain = blockchain + } else { + return fmt.Errorf("Failed to set Blockchain for pipe; already set") + } + return nil +} + +func (pipe *erisMintPipe) GetBlockchain() blockchain_types.Blockchain { + return pipe.blockchain +} + +func (pipe *erisMintPipe) SetConsensus( + consensus consensus_types.Consensus) error { + if pipe.consensus == nil { + pipe.consensus = consensus } else { return fmt.Errorf("Failed to set consensus engine for pipe; already set") } return nil } -func (pipe *erisMintPipe) GetConsensusEngine() definitions.ConsensusEngine { - return pipe.consensusEngine +func (pipe *erisMintPipe) GetConsensus() consensus_types.Consensus { + return pipe.consensus } func (pipe *erisMintPipe) GetTendermintPipe() (definitions.TendermintPipe, @@ -227,7 +241,7 @@ func (pipe *erisMintPipe) GetTendermintPipe() (definitions.TendermintPipe, func (pipe *erisMintPipe) consensusAndManagerEvents() edb_event.EventEmitter { // NOTE: [Silas] We could initialise this lazily and use the cached instance, // but for the time being that feels like a premature optimisation - return edb_event.Multiplex(pipe.events, pipe.consensusEngine.Events()) + return edb_event.Multiplex(pipe.events, pipe.consensus.Events()) } //------------------------------------------------------------------------------ @@ -251,7 +265,7 @@ func (pipe *erisMintPipe) Subscribe(event string, }) return &rpc_tm_types.ResultSubscribe{ SubscriptionId: subscriptionId, - Event: event, + Event: event, }, nil } @@ -261,43 +275,49 @@ func (pipe *erisMintPipe) Unsubscribe(subscriptionId string) (*rpc_tm_types.Resu pipe.consensusAndManagerEvents().Unsubscribe(subscriptionId) return &rpc_tm_types.ResultUnsubscribe{SubscriptionId: subscriptionId}, nil } - -func (pipe *erisMintPipe) Status() (*rpc_tm_types.ResultStatus, error) { - memoryDatabase := db.NewMemDB() +func (pipe *erisMintPipe) GenesisState() *state.State { if pipe.genesisState == nil { + memoryDatabase := db.NewMemDB() pipe.genesisState = state.MakeGenesisState(memoryDatabase, pipe.genesisDoc) } - genesisHash := pipe.genesisState.Hash() - if pipe.consensusEngine == nil { + return pipe.genesisState +} + +func (pipe *erisMintPipe) GenesisHash() []byte { + return pipe.GenesisState().Hash() +} + +func (pipe *erisMintPipe) Status() (*rpc_tm_types.ResultStatus, error) { + if pipe.consensus == nil { return nil, fmt.Errorf("Consensus Engine is not set in pipe.") } - latestHeight := pipe.consensusEngine.Height() + latestHeight := pipe.blockchain.Height() var ( latestBlockMeta *tm_types.BlockMeta latestBlockHash []byte latestBlockTime int64 ) if latestHeight != 0 { - latestBlockMeta = pipe.consensusEngine.LoadBlockMeta(latestHeight) + latestBlockMeta = pipe.blockchain.BlockMeta(latestHeight) latestBlockHash = latestBlockMeta.Hash latestBlockTime = latestBlockMeta.Header.Time.UnixNano() } return &rpc_tm_types.ResultStatus{ - NodeInfo: pipe.consensusEngine.NodeInfo(), - GenesisHash: genesisHash, - PubKey: pipe.consensusEngine.PublicValidatorKey(), + NodeInfo: pipe.consensus.NodeInfo(), + GenesisHash: pipe.GenesisHash(), + PubKey: pipe.consensus.PublicValidatorKey(), LatestBlockHash: latestBlockHash, LatestBlockHeight: latestHeight, LatestBlockTime: latestBlockTime}, nil } func (pipe *erisMintPipe) NetInfo() (*rpc_tm_types.ResultNetInfo, error) { - listening := pipe.consensusEngine.IsListening() + listening := pipe.consensus.IsListening() listeners := []string{} - for _, listener := range pipe.consensusEngine.Listeners() { + for _, listener := range pipe.consensus.Listeners() { listeners = append(listeners, listener.String()) } - peers := pipe.consensusEngine.Peers() + peers := pipe.consensus.Peers() return &rpc_tm_types.ResultNetInfo{ Listening: listening, Listeners: listeners, @@ -494,7 +514,7 @@ func (pipe *erisMintPipe) ListNames() (*rpc_tm_types.ResultListNames, error) { // NOTE: txs must be signed func (pipe *erisMintPipe) BroadcastTxAsync(tx txs.Tx) ( *rpc_tm_types.ResultBroadcastTx, error) { - err := pipe.consensusEngine.BroadcastTransaction(txs.EncodeTx(tx), nil) + err := pipe.consensus.BroadcastTransaction(txs.EncodeTx(tx), nil) if err != nil { return nil, fmt.Errorf("Error broadcasting txs: %v", err) } @@ -504,7 +524,7 @@ func (pipe *erisMintPipe) BroadcastTxAsync(tx txs.Tx) ( func (pipe *erisMintPipe) BroadcastTxSync(tx txs.Tx) (*rpc_tm_types.ResultBroadcastTx, error) { responseChannel := make(chan *tmsp_types.Response, 1) - err := pipe.consensusEngine.BroadcastTransaction(txs.EncodeTx(tx), + err := pipe.consensus.BroadcastTransaction(txs.EncodeTx(tx), func(res *tmsp_types.Response) { responseChannel <- res }) @@ -550,7 +570,7 @@ func (pipe *erisMintPipe) BroadcastTxSync(tx txs.Tx) (*rpc_tm_types.ResultBroadc func (pipe *erisMintPipe) BlockchainInfo(minHeight, maxHeight, maxBlockLookback int) (*rpc_tm_types.ResultBlockchainInfo, error) { - latestHeight := pipe.consensusEngine.Height() + latestHeight := pipe.blockchain.Height() if maxHeight < 1 { maxHeight = latestHeight @@ -563,7 +583,7 @@ func (pipe *erisMintPipe) BlockchainInfo(minHeight, maxHeight, blockMetas := []*tm_types.BlockMeta{} for height := maxHeight; height >= minHeight; height-- { - blockMeta := pipe.consensusEngine.LoadBlockMeta(height) + blockMeta := pipe.blockchain.BlockMeta(height) blockMetas = append(blockMetas, blockMeta) } diff --git a/rpc/tendermint/core/routes.go b/rpc/tendermint/core/routes.go index 7fc6b03f6e17052779761b4189b8beb86e09fd8c..714c1066d290c7f5cddf148e1064ae9eaf488cd0 100644 --- a/rpc/tendermint/core/routes.go +++ b/rpc/tendermint/core/routes.go @@ -44,10 +44,10 @@ func (tmRoutes *TendermintRoutes) GetRoutes() map[string]*rpc.RPCFunc { // TODO: hookup "blockchain": rpc.NewRPCFunc(tmRoutes.BlockchainInfo, "minHeight,maxHeight"), // "get_block": rpc.NewRPCFunc(GetBlock, "height"), - //"list_validators": rpc.NewRPCFunc(ListValidators, ""), + // "list_validators": rpc.NewRPCFunc(ListValidators, ""), // "dump_consensus_state": rpc.NewRPCFunc(DumpConsensusState, ""), // "list_unconfirmed_txs": rpc.NewRPCFunc(ListUnconfirmedTxs, ""), - // subscribe/unsubscribe are reserved for websocket events. + // TODO: [Silas] do we also carry forward "consensus_state" as in v0? } return routes } diff --git a/rpc/tendermint/core/types/responses.go b/rpc/tendermint/core/types/responses.go index ed050c03e8be5d16372f88283563eaa3d707824c..cacb5f5ff0beb38fc2fc7ec60807a8d9cb079571 100644 --- a/rpc/tendermint/core/types/responses.go +++ b/rpc/tendermint/core/types/responses.go @@ -7,6 +7,7 @@ import ( "github.com/eris-ltd/eris-db/txs" "github.com/tendermint/tendermint/types" + consensus_types "github.com/eris-ltd/eris-db/consensus/types" "github.com/tendermint/go-crypto" "github.com/tendermint/go-p2p" "github.com/tendermint/go-rpc/types" @@ -60,7 +61,7 @@ type ResultStatus struct { } type ResultSubscribe struct { - Event string `json:"event"` + Event string `json:"event"` SubscriptionId string `json:"subscription_id"` } @@ -69,14 +70,9 @@ type ResultUnsubscribe struct { } type ResultNetInfo struct { - Listening bool `json:"listening"` - Listeners []string `json:"listeners"` - Peers []Peer `json:"peers"` -} - -type Peer struct { - p2p.NodeInfo `json:"node_info"` - IsOutbound bool `json:"is_outbound"` + Listening bool `json:"listening"` + Listeners []string `json:"listeners"` + Peers []consensus_types.Peer `json:"peers"` } type ResultListValidators struct { diff --git a/rpc/v0/json_service.go b/rpc/v0/json_service.go index 1e71bdc56b4b4b7888437a5e7c6d5f606c318233..4c43f533432fdd1e2da6c1dc5f46233ede862069 100644 --- a/rpc/v0/json_service.go +++ b/rpc/v0/json_service.go @@ -64,7 +64,7 @@ func NewErisDbJsonService(codec rpc.Codec, pipe definitions.Pipe, eventSubs *event.EventSubscriptions) server.HttpService { tmhttps := &ErisDbJsonService{codec: codec, pipe: pipe, eventSubs: eventSubs} - mtds := &ErisDbMethods{codec, pipe} + mtds := NewErisDbMethods(codec, pipe) dhMap := mtds.getMethods() // Events diff --git a/rpc/v0/methods.go b/rpc/v0/methods.go index f5f5540902711ac6a4dd667757e6c4385291ced1..b3aac0e9d5ea0a8a9d53dd18c283151d3e0900c8 100644 --- a/rpc/v0/methods.go +++ b/rpc/v0/methods.go @@ -1,8 +1,11 @@ package rpc_v0 import ( + "github.com/eris-ltd/eris-db/blockchain" + pipes "github.com/eris-ltd/eris-db/core/pipes" core_types "github.com/eris-ltd/eris-db/core/types" definitions "github.com/eris-ltd/eris-db/definitions" + "github.com/eris-ltd/eris-db/event" rpc "github.com/eris-ltd/eris-db/rpc" "github.com/eris-ltd/eris-db/txs" ) @@ -50,54 +53,65 @@ const ( // The rpc method handlers. type ErisDbMethods struct { - codec rpc.Codec - pipe definitions.Pipe + codec rpc.Codec + pipe definitions.Pipe + filterFactory *event.FilterFactory +} + +func NewErisDbMethods(codec rpc.Codec, + pipe definitions.Pipe) *ErisDbMethods { + + return &ErisDbMethods{ + codec: codec, + pipe: pipe, + filterFactory: blockchain.NewBlockchainFilterFactory(), + } } // Used to handle requests. interface{} param is a wildcard used for example with socket events. type RequestHandlerFunc func(*rpc.RPCRequest, interface{}) (interface{}, int, error) // Private. Create a method name -> method handler map. -func (this *ErisDbMethods) getMethods() map[string]RequestHandlerFunc { +func (erisDbMethods *ErisDbMethods) getMethods() map[string]RequestHandlerFunc { dhMap := make(map[string]RequestHandlerFunc) // Accounts - dhMap[GET_ACCOUNTS] = this.Accounts - dhMap[GET_ACCOUNT] = this.Account - dhMap[GET_STORAGE] = this.AccountStorage - dhMap[GET_STORAGE_AT] = this.AccountStorageAt - dhMap[GEN_PRIV_ACCOUNT] = this.GenPrivAccount - dhMap[GEN_PRIV_ACCOUNT_FROM_KEY] = this.GenPrivAccountFromKey + dhMap[GET_ACCOUNTS] = erisDbMethods.Accounts + dhMap[GET_ACCOUNT] = erisDbMethods.Account + dhMap[GET_STORAGE] = erisDbMethods.AccountStorage + dhMap[GET_STORAGE_AT] = erisDbMethods.AccountStorageAt + dhMap[GEN_PRIV_ACCOUNT] = erisDbMethods.GenPrivAccount + dhMap[GEN_PRIV_ACCOUNT_FROM_KEY] = erisDbMethods.GenPrivAccountFromKey // Blockchain - dhMap[GET_BLOCKCHAIN_INFO] = this.BlockchainInfo - dhMap[GET_GENESIS_HASH] = this.GenesisHash - dhMap[GET_LATEST_BLOCK_HEIGHT] = this.LatestBlockHeight - dhMap[GET_LATEST_BLOCK] = this.LatestBlock - dhMap[GET_BLOCKS] = this.Blocks - dhMap[GET_BLOCK] = this.Block + dhMap[GET_BLOCKCHAIN_INFO] = erisDbMethods.BlockchainInfo + dhMap[GET_GENESIS_HASH] = erisDbMethods.GenesisHash + dhMap[GET_LATEST_BLOCK_HEIGHT] = erisDbMethods.LatestBlockHeight + dhMap[GET_LATEST_BLOCK] = erisDbMethods.LatestBlock + dhMap[GET_BLOCKS] = erisDbMethods.Blocks + dhMap[GET_BLOCK] = erisDbMethods.Block // Consensus - dhMap[GET_CONSENSUS_STATE] = this.ConsensusState - dhMap[GET_VALIDATORS] = this.Validators + dhMap[GET_CONSENSUS_STATE] = erisDbMethods.ConsensusState + dhMap[GET_VALIDATORS] = erisDbMethods.Validators // Network - dhMap[GET_NETWORK_INFO] = this.NetworkInfo - dhMap[GET_CLIENT_VERSION] = this.ClientVersion - dhMap[GET_MONIKER] = this.Moniker - dhMap[GET_CHAIN_ID] = this.ChainId - dhMap[IS_LISTENING] = this.Listening - dhMap[GET_LISTENERS] = this.Listeners - dhMap[GET_PEERS] = this.Peers - dhMap[GET_PEER] = this.Peer + dhMap[GET_NETWORK_INFO] = erisDbMethods.NetworkInfo + dhMap[GET_CLIENT_VERSION] = erisDbMethods.ClientVersion + dhMap[GET_MONIKER] = erisDbMethods.Moniker + dhMap[GET_CHAIN_ID] = erisDbMethods.ChainId + dhMap[IS_LISTENING] = erisDbMethods.Listening + dhMap[GET_LISTENERS] = erisDbMethods.Listeners + dhMap[GET_PEERS] = erisDbMethods.Peers + dhMap[GET_PEER] = erisDbMethods.Peer // Txs - dhMap[CALL] = this.Call - dhMap[CALL_CODE] = this.CallCode - dhMap[BROADCAST_TX] = this.BroadcastTx - dhMap[GET_UNCONFIRMED_TXS] = this.UnconfirmedTxs - dhMap[SIGN_TX] = this.SignTx - dhMap[TRANSACT] = this.Transact - dhMap[TRANSACT_AND_HOLD] = this.TransactAndHold - dhMap[TRANSACT_NAMEREG] = this.TransactNameReg + dhMap[CALL] = erisDbMethods.Call + dhMap[CALL_CODE] = erisDbMethods.CallCode + dhMap[BROADCAST_TX] = erisDbMethods.BroadcastTx + dhMap[GET_UNCONFIRMED_TXS] = erisDbMethods.UnconfirmedTxs + dhMap[SIGN_TX] = erisDbMethods.SignTx + dhMap[TRANSACT] = erisDbMethods.Transact + dhMap[TRANSACT_AND_HOLD] = erisDbMethods.TransactAndHold + dhMap[TRANSACT_NAMEREG] = erisDbMethods.TransactNameReg // Namereg - dhMap[GET_NAMEREG_ENTRY] = this.NameRegEntry - dhMap[GET_NAMEREG_ENTRIES] = this.NameRegEntries + dhMap[GET_NAMEREG_ENTRY] = erisDbMethods.NameRegEntry + dhMap[GET_NAMEREG_ENTRIES] = erisDbMethods.NameRegEntries return dhMap } @@ -107,81 +121,81 @@ func (this *ErisDbMethods) getMethods() map[string]RequestHandlerFunc { // *************************************** Accounts *************************************** -func (this *ErisDbMethods) GenPrivAccount(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - pac, errC := this.pipe.Accounts().GenPrivAccount() +func (erisDbMethods *ErisDbMethods) GenPrivAccount(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { + pac, errC := erisDbMethods.pipe.Accounts().GenPrivAccount() if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } return pac, 0, nil } -func (this *ErisDbMethods) GenPrivAccountFromKey(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { +func (erisDbMethods *ErisDbMethods) GenPrivAccountFromKey(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { param := &PrivKeyParam{} - err := this.codec.DecodeBytes(param, request.Params) + err := erisDbMethods.codec.DecodeBytes(param, request.Params) if err != nil { return nil, rpc.INVALID_PARAMS, err } privKey := param.PrivKey - pac, errC := this.pipe.Accounts().GenPrivAccountFromKey(privKey) + pac, errC := erisDbMethods.pipe.Accounts().GenPrivAccountFromKey(privKey) if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } return pac, 0, nil } -func (this *ErisDbMethods) Account(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { +func (erisDbMethods *ErisDbMethods) Account(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { param := &AddressParam{} - err := this.codec.DecodeBytes(param, request.Params) + err := erisDbMethods.codec.DecodeBytes(param, request.Params) if err != nil { return nil, rpc.INVALID_PARAMS, err } address := param.Address // TODO is address check? - account, errC := this.pipe.Accounts().Account(address) + account, errC := erisDbMethods.pipe.Accounts().Account(address) if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } return account, 0, nil } -func (this *ErisDbMethods) Accounts(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { +func (erisDbMethods *ErisDbMethods) Accounts(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { param := &AccountsParam{} - err := this.codec.DecodeBytes(param, request.Params) + err := erisDbMethods.codec.DecodeBytes(param, request.Params) if err != nil { return nil, rpc.INVALID_PARAMS, err } - list, errC := this.pipe.Accounts().Accounts(param.Filters) + list, errC := erisDbMethods.pipe.Accounts().Accounts(param.Filters) if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } return list, 0, nil } -func (this *ErisDbMethods) AccountStorage(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { +func (erisDbMethods *ErisDbMethods) AccountStorage(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { param := &AddressParam{} - err := this.codec.DecodeBytes(param, request.Params) + err := erisDbMethods.codec.DecodeBytes(param, request.Params) if err != nil { return nil, rpc.INVALID_PARAMS, err } address := param.Address - storage, errC := this.pipe.Accounts().Storage(address) + storage, errC := erisDbMethods.pipe.Accounts().Storage(address) if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } return storage, 0, nil } -func (this *ErisDbMethods) AccountStorageAt(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { +func (erisDbMethods *ErisDbMethods) AccountStorageAt(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { param := &StorageAtParam{} - err := this.codec.DecodeBytes(param, request.Params) + err := erisDbMethods.codec.DecodeBytes(param, request.Params) if err != nil { return nil, rpc.INVALID_PARAMS, err } address := param.Address key := param.Key - storageItem, errC := this.pipe.Accounts().StorageAt(address, key) + storageItem, errC := erisDbMethods.pipe.Accounts().StorageAt(address, key) if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } @@ -190,150 +204,129 @@ func (this *ErisDbMethods) AccountStorageAt(request *rpc.RPCRequest, requester i // *************************************** Blockchain ************************************ -func (this *ErisDbMethods) BlockchainInfo(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - status, errC := this.pipe.Blockchain().Info() - if errC != nil { - return nil, rpc.INTERNAL_ERROR, errC - } - return status, 0, nil +func (erisDbMethods *ErisDbMethods) BlockchainInfo(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { + return pipes.BlockchainInfo(erisDbMethods.pipe), 0, nil } -func (this *ErisDbMethods) ChainId(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - chainId, errC := this.pipe.Blockchain().ChainId() - if errC != nil { - return nil, rpc.INTERNAL_ERROR, errC - } +func (erisDbMethods *ErisDbMethods) ChainId(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { + chainId := erisDbMethods.pipe.Blockchain().ChainId() return &core_types.ChainId{chainId}, 0, nil } -func (this *ErisDbMethods) GenesisHash(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - hash, errC := this.pipe.Blockchain().GenesisHash() - if errC != nil { - return nil, rpc.INTERNAL_ERROR, errC - } +func (erisDbMethods *ErisDbMethods) GenesisHash(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { + hash := erisDbMethods.pipe.GenesisHash() return &core_types.GenesisHash{hash}, 0, nil } -func (this *ErisDbMethods) LatestBlockHeight(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - height, errC := this.pipe.Blockchain().LatestBlockHeight() - if errC != nil { - return nil, rpc.INTERNAL_ERROR, errC - } +func (erisDbMethods *ErisDbMethods) LatestBlockHeight(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { + height := erisDbMethods.pipe.Blockchain().Height() return &core_types.LatestBlockHeight{height}, 0, nil } -func (this *ErisDbMethods) LatestBlock(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - - block, errC := this.pipe.Blockchain().LatestBlock() - if errC != nil { - return nil, rpc.INTERNAL_ERROR, errC - } +func (erisDbMethods *ErisDbMethods) LatestBlock(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { + latestHeight := erisDbMethods.pipe.Blockchain().Height() + block := erisDbMethods.pipe.Blockchain().Block(latestHeight) return block, 0, nil } -func (this *ErisDbMethods) Blocks(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { +func (erisDbMethods *ErisDbMethods) Blocks(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { param := &BlocksParam{} - err := this.codec.DecodeBytes(param, request.Params) + err := erisDbMethods.codec.DecodeBytes(param, request.Params) if err != nil { return nil, rpc.INVALID_PARAMS, err } - blocks, errC := this.pipe.Blockchain().Blocks(param.Filters) + blocks, errC := blockchain.FilterBlocks(erisDbMethods.pipe.Blockchain(), erisDbMethods.filterFactory, param.Filters) if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } return blocks, 0, nil } -func (this *ErisDbMethods) Block(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { +func (erisDbMethods *ErisDbMethods) Block(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { param := &HeightParam{} - err := this.codec.DecodeBytes(param, request.Params) + err := erisDbMethods.codec.DecodeBytes(param, request.Params) if err != nil { return nil, rpc.INVALID_PARAMS, err } height := param.Height - block, errC := this.pipe.Blockchain().Block(height) - if errC != nil { - return nil, rpc.INTERNAL_ERROR, errC - } + block := erisDbMethods.pipe.Blockchain().Block(height) return block, 0, nil } // *************************************** Consensus ************************************ -func (this *ErisDbMethods) ConsensusState(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - state, errC := this.pipe.Consensus().State() - if errC != nil { - return nil, rpc.INTERNAL_ERROR, errC - } +func (erisDbMethods *ErisDbMethods) ConsensusState(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { + // TODO: [Silas] erisDbMethods has not implemented this since the refactor + // core_types.FromRoundState() will do it, but only if we have access to + // Tendermint's RonudState.. + state := &core_types.ConsensusState{} return state, 0, nil } -func (this *ErisDbMethods) Validators(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - validators, errC := this.pipe.Consensus().Validators() - if errC != nil { - return nil, rpc.INTERNAL_ERROR, errC - } +func (erisDbMethods *ErisDbMethods) Validators(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { + // TODO: [Silas] erisDbMethods has not implemented this since the refactor + validators := &core_types.ValidatorList{} return validators, 0, nil } // *************************************** Net ************************************ -func (this *ErisDbMethods) NetworkInfo(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - info, errC := this.pipe.Net().Info() +func (erisDbMethods *ErisDbMethods) NetworkInfo(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { + info, errC := erisDbMethods.pipe.Net().Info() if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } return info, 0, nil } -func (this *ErisDbMethods) ClientVersion(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - version, errC := this.pipe.Net().ClientVersion() +func (erisDbMethods *ErisDbMethods) ClientVersion(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { + version, errC := erisDbMethods.pipe.Net().ClientVersion() if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } return &core_types.ClientVersion{version}, 0, nil } -func (this *ErisDbMethods) Moniker(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - moniker, errC := this.pipe.Net().Moniker() +func (erisDbMethods *ErisDbMethods) Moniker(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { + moniker, errC := erisDbMethods.pipe.Net().Moniker() if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } return &core_types.Moniker{moniker}, 0, nil } -func (this *ErisDbMethods) Listening(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - listening, errC := this.pipe.Net().Listening() +func (erisDbMethods *ErisDbMethods) Listening(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { + listening, errC := erisDbMethods.pipe.Net().Listening() if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } return &core_types.Listening{listening}, 0, nil } -func (this *ErisDbMethods) Listeners(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - listeners, errC := this.pipe.Net().Listeners() +func (erisDbMethods *ErisDbMethods) Listeners(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { + listeners, errC := erisDbMethods.pipe.Net().Listeners() if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } return &core_types.Listeners{listeners}, 0, nil } -func (this *ErisDbMethods) Peers(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - peers, errC := this.pipe.Net().Peers() +func (erisDbMethods *ErisDbMethods) Peers(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { + peers, errC := erisDbMethods.pipe.Net().Peers() if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } return peers, 0, nil } -func (this *ErisDbMethods) Peer(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { +func (erisDbMethods *ErisDbMethods) Peer(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { param := &PeerParam{} - err := this.codec.DecodeBytes(param, request.Params) + err := erisDbMethods.codec.DecodeBytes(param, request.Params) if err != nil { return nil, rpc.INVALID_PARAMS, err } address := param.Address - peer, errC := this.pipe.Net().Peer(address) + peer, errC := erisDbMethods.pipe.Net().Peer(address) if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } @@ -342,107 +335,107 @@ func (this *ErisDbMethods) Peer(request *rpc.RPCRequest, requester interface{}) // *************************************** Txs ************************************ -func (this *ErisDbMethods) Call(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { +func (erisDbMethods *ErisDbMethods) Call(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { param := &CallParam{} - err := this.codec.DecodeBytes(param, request.Params) + err := erisDbMethods.codec.DecodeBytes(param, request.Params) if err != nil { return nil, rpc.INVALID_PARAMS, err } from := param.From to := param.Address data := param.Data - call, errC := this.pipe.Transactor().Call(from, to, data) + call, errC := erisDbMethods.pipe.Transactor().Call(from, to, data) if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } return call, 0, nil } -func (this *ErisDbMethods) CallCode(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { +func (erisDbMethods *ErisDbMethods) CallCode(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { param := &CallCodeParam{} - err := this.codec.DecodeBytes(param, request.Params) + err := erisDbMethods.codec.DecodeBytes(param, request.Params) if err != nil { return nil, rpc.INVALID_PARAMS, err } from := param.From code := param.Code data := param.Data - call, errC := this.pipe.Transactor().CallCode(from, code, data) + call, errC := erisDbMethods.pipe.Transactor().CallCode(from, code, data) if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } return call, 0, nil } -func (this *ErisDbMethods) BroadcastTx(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { +func (erisDbMethods *ErisDbMethods) BroadcastTx(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { param := &txs.CallTx{} - err := this.codec.DecodeBytes(param, request.Params) + err := erisDbMethods.codec.DecodeBytes(param, request.Params) if err != nil { return nil, rpc.INVALID_PARAMS, err } - receipt, errC := this.pipe.Transactor().BroadcastTx(param) + receipt, errC := erisDbMethods.pipe.Transactor().BroadcastTx(param) if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } return receipt, 0, nil } -func (this *ErisDbMethods) Transact(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { +func (erisDbMethods *ErisDbMethods) Transact(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { param := &TransactParam{} - err := this.codec.DecodeBytes(param, request.Params) + err := erisDbMethods.codec.DecodeBytes(param, request.Params) if err != nil { return nil, rpc.INVALID_PARAMS, err } - receipt, errC := this.pipe.Transactor().Transact(param.PrivKey, param.Address, param.Data, param.GasLimit, param.Fee) + receipt, errC := erisDbMethods.pipe.Transactor().Transact(param.PrivKey, param.Address, param.Data, param.GasLimit, param.Fee) if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } return receipt, 0, nil } -func (this *ErisDbMethods) TransactAndHold(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { +func (erisDbMethods *ErisDbMethods) TransactAndHold(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { param := &TransactParam{} - err := this.codec.DecodeBytes(param, request.Params) + err := erisDbMethods.codec.DecodeBytes(param, request.Params) if err != nil { return nil, rpc.INVALID_PARAMS, err } - ce, errC := this.pipe.Transactor().TransactAndHold(param.PrivKey, param.Address, param.Data, param.GasLimit, param.Fee) + ce, errC := erisDbMethods.pipe.Transactor().TransactAndHold(param.PrivKey, param.Address, param.Data, param.GasLimit, param.Fee) if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } return ce, 0, nil } -func (this *ErisDbMethods) TransactNameReg(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { +func (erisDbMethods *ErisDbMethods) TransactNameReg(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { param := &TransactNameRegParam{} - err := this.codec.DecodeBytes(param, request.Params) + err := erisDbMethods.codec.DecodeBytes(param, request.Params) if err != nil { return nil, rpc.INVALID_PARAMS, err } - receipt, errC := this.pipe.Transactor().TransactNameReg(param.PrivKey, param.Name, param.Data, param.Amount, param.Fee) + receipt, errC := erisDbMethods.pipe.Transactor().TransactNameReg(param.PrivKey, param.Name, param.Data, param.Amount, param.Fee) if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } return receipt, 0, nil } -func (this *ErisDbMethods) UnconfirmedTxs(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - txs, errC := this.pipe.Transactor().UnconfirmedTxs() +func (erisDbMethods *ErisDbMethods) UnconfirmedTxs(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { + txs, errC := erisDbMethods.pipe.Transactor().UnconfirmedTxs() if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } return txs, 0, nil } -func (this *ErisDbMethods) SignTx(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { +func (erisDbMethods *ErisDbMethods) SignTx(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { param := &SignTxParam{} - err := this.codec.DecodeBytes(param, request.Params) + err := erisDbMethods.codec.DecodeBytes(param, request.Params) if err != nil { return nil, rpc.INVALID_PARAMS, err } tx := param.Tx pAccs := param.PrivAccounts - txRet, errC := this.pipe.Transactor().SignTx(tx, pAccs) + txRet, errC := erisDbMethods.pipe.Transactor().SignTx(tx, pAccs) if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } @@ -451,28 +444,28 @@ func (this *ErisDbMethods) SignTx(request *rpc.RPCRequest, requester interface{} // *************************************** Name Registry *************************************** -func (this *ErisDbMethods) NameRegEntry(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { +func (erisDbMethods *ErisDbMethods) NameRegEntry(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { param := &NameRegEntryParam{} - err := this.codec.DecodeBytes(param, request.Params) + err := erisDbMethods.codec.DecodeBytes(param, request.Params) if err != nil { return nil, rpc.INVALID_PARAMS, err } name := param.Name // TODO is address check? - entry, errC := this.pipe.NameReg().Entry(name) + entry, errC := erisDbMethods.pipe.NameReg().Entry(name) if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } return entry, 0, nil } -func (this *ErisDbMethods) NameRegEntries(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { +func (erisDbMethods *ErisDbMethods) NameRegEntries(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { param := &FilterListParam{} - err := this.codec.DecodeBytes(param, request.Params) + err := erisDbMethods.codec.DecodeBytes(param, request.Params) if err != nil { return nil, rpc.INVALID_PARAMS, err } - list, errC := this.pipe.NameReg().Entries(param.Filters) + list, errC := erisDbMethods.pipe.NameReg().Entries(param.Filters) if errC != nil { return nil, rpc.INTERNAL_ERROR, errC } diff --git a/rpc/v0/restServer.go b/rpc/v0/restServer.go index a1e1e01f5a780a09ed61d66fd56e92654b10f798..d6ad13bd29589c3ebbff44d86696446ace251dce 100644 --- a/rpc/v0/restServer.go +++ b/rpc/v0/restServer.go @@ -8,6 +8,8 @@ import ( "github.com/gin-gonic/gin" + "github.com/eris-ltd/eris-db/blockchain" + "github.com/eris-ltd/eris-db/core/pipes" core_types "github.com/eris-ltd/eris-db/core/types" definitions "github.com/eris-ltd/eris-db/definitions" event "github.com/eris-ltd/eris-db/event" @@ -21,465 +23,453 @@ import ( // TODO more routers. Also, start looking into how better status codes // can be gotten. type RestServer struct { - codec rpc.Codec - pipe definitions.Pipe - eventSubs *event.EventSubscriptions - running bool + codec rpc.Codec + pipe definitions.Pipe + eventSubs *event.EventSubscriptions + filterFactory *event.FilterFactory + running bool } // Create a new rest server. func NewRestServer(codec rpc.Codec, pipe definitions.Pipe, eventSubs *event.EventSubscriptions) *RestServer { - return &RestServer{codec: codec, pipe: pipe, eventSubs: eventSubs} + return &RestServer{ + codec: codec, + pipe: pipe, + eventSubs: eventSubs, + filterFactory: blockchain.NewBlockchainFilterFactory(), + } } // Starting the server means registering all the handlers with the router. -func (this *RestServer) Start(config *server.ServerConfig, router *gin.Engine) { +func (restServer *RestServer) Start(config *server.ServerConfig, router *gin.Engine) { // Accounts - router.GET("/accounts", parseSearchQuery, this.handleAccounts) - router.GET("/accounts/:address", addressParam, this.handleAccount) - router.GET("/accounts/:address/storage", addressParam, this.handleStorage) - router.GET("/accounts/:address/storage/:key", addressParam, keyParam, this.handleStorageAt) + router.GET("/accounts", parseSearchQuery, restServer.handleAccounts) + router.GET("/accounts/:address", addressParam, restServer.handleAccount) + router.GET("/accounts/:address/storage", addressParam, restServer.handleStorage) + router.GET("/accounts/:address/storage/:key", addressParam, keyParam, restServer.handleStorageAt) // Blockchain - router.GET("/blockchain", this.handleBlockchainInfo) - router.GET("/blockchain/chain_id", this.handleChainId) - router.GET("/blockchain/genesis_hash", this.handleGenesisHash) - router.GET("/blockchain/latest_block_height", this.handleLatestBlockHeight) - router.GET("/blockchain/latest_block", this.handleLatestBlock) - router.GET("/blockchain/blocks", parseSearchQuery, this.handleBlocks) - router.GET("/blockchain/block/:height", heightParam, this.handleBlock) + router.GET("/blockchain", restServer.handleBlockchainInfo) + router.GET("/blockchain/chain_id", restServer.handleChainId) + router.GET("/blockchain/genesis_hash", restServer.handleGenesisHash) + router.GET("/blockchain/latest_block_height", restServer.handleLatestBlockHeight) + router.GET("/blockchain/latest_block", restServer.handleLatestBlock) + router.GET("/blockchain/blocks", parseSearchQuery, restServer.handleBlocks) + router.GET("/blockchain/block/:height", heightParam, restServer.handleBlock) // Consensus - router.GET("/consensus", this.handleConsensusState) - router.GET("/consensus/validators", this.handleValidatorList) + router.GET("/consensus", restServer.handleConsensusState) + router.GET("/consensus/validators", restServer.handleValidatorList) // Events - router.POST("/event_subs", this.handleEventSubscribe) - router.GET("/event_subs/:id", this.handleEventPoll) - router.DELETE("/event_subs/:id", this.handleEventUnsubscribe) + router.POST("/event_subs", restServer.handleEventSubscribe) + router.GET("/event_subs/:id", restServer.handleEventPoll) + router.DELETE("/event_subs/:id", restServer.handleEventUnsubscribe) // NameReg - router.GET("/namereg", parseSearchQuery, this.handleNameRegEntries) - router.GET("/namereg/:key", nameParam, this.handleNameRegEntry) + router.GET("/namereg", parseSearchQuery, restServer.handleNameRegEntries) + router.GET("/namereg/:key", nameParam, restServer.handleNameRegEntry) // Network - router.GET("/network", this.handleNetworkInfo) - router.GET("/network/client_version", this.handleClientVersion) - router.GET("/network/moniker", this.handleMoniker) - router.GET("/network/listening", this.handleListening) - router.GET("/network/listeners", this.handleListeners) - router.GET("/network/peers", this.handlePeers) - router.GET("/network/peers/:address", peerAddressParam, this.handlePeer) + router.GET("/network", restServer.handleNetworkInfo) + router.GET("/network/client_version", restServer.handleClientVersion) + router.GET("/network/moniker", restServer.handleMoniker) + router.GET("/network/listening", restServer.handleListening) + router.GET("/network/listeners", restServer.handleListeners) + router.GET("/network/peers", restServer.handlePeers) + router.GET("/network/peers/:address", peerAddressParam, restServer.handlePeer) // Tx related (TODO get txs has still not been implemented) - router.POST("/txpool", this.handleBroadcastTx) - router.GET("/txpool", this.handleUnconfirmedTxs) + router.POST("/txpool", restServer.handleBroadcastTx) + router.GET("/txpool", restServer.handleUnconfirmedTxs) // Code execution - router.POST("/calls", this.handleCall) - router.POST("/codecalls", this.handleCallCode) + router.POST("/calls", restServer.handleCall) + router.POST("/codecalls", restServer.handleCallCode) // Unsafe - router.GET("/unsafe/pa_generator", this.handleGenPrivAcc) - router.POST("/unsafe/txpool", parseTxModifier, this.handleTransact) - router.POST("/unsafe/namereg/txpool", this.handleTransactNameReg) - router.POST("/unsafe/tx_signer", this.handleSignTx) - this.running = true + router.GET("/unsafe/pa_generator", restServer.handleGenPrivAcc) + router.POST("/unsafe/txpool", parseTxModifier, restServer.handleTransact) + router.POST("/unsafe/namereg/txpool", restServer.handleTransactNameReg) + router.POST("/unsafe/tx_signer", restServer.handleSignTx) + restServer.running = true } // Is the server currently running? -func (this *RestServer) Running() bool { - return this.running +func (restServer *RestServer) Running() bool { + return restServer.running } // Shut the server down. Does nothing. -func (this *RestServer) ShutDown() { - this.running = false +func (restServer *RestServer) ShutDown() { + restServer.running = false } // ********************************* Accounts ********************************* -func (this *RestServer) handleGenPrivAcc(c *gin.Context) { +func (restServer *RestServer) handleGenPrivAcc(c *gin.Context) { addr := &AddressParam{} var acc interface{} var err error if addr.Address == nil || len(addr.Address) == 0 { - acc, err = this.pipe.Accounts().GenPrivAccount() + acc, err = restServer.pipe.Accounts().GenPrivAccount() } else { - acc, err = this.pipe.Accounts().GenPrivAccountFromKey(addr.Address) + acc, err = restServer.pipe.Accounts().GenPrivAccountFromKey(addr.Address) } if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(acc, c.Writer) + restServer.codec.Encode(acc, c.Writer) } -func (this *RestServer) handleAccounts(c *gin.Context) { +func (restServer *RestServer) handleAccounts(c *gin.Context) { var filters []*event.FilterData fs, exists := c.Get("filters") if exists { filters = fs.([]*event.FilterData) } - accs, err := this.pipe.Accounts().Accounts(filters) + accs, err := restServer.pipe.Accounts().Accounts(filters) if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(accs, c.Writer) + restServer.codec.Encode(accs, c.Writer) } -func (this *RestServer) handleAccount(c *gin.Context) { +func (restServer *RestServer) handleAccount(c *gin.Context) { addr := c.MustGet("addrBts").([]byte) - acc, err := this.pipe.Accounts().Account(addr) + acc, err := restServer.pipe.Accounts().Account(addr) if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(acc, c.Writer) + restServer.codec.Encode(acc, c.Writer) } -func (this *RestServer) handleStorage(c *gin.Context) { +func (restServer *RestServer) handleStorage(c *gin.Context) { addr := c.MustGet("addrBts").([]byte) - s, err := this.pipe.Accounts().Storage(addr) + s, err := restServer.pipe.Accounts().Storage(addr) if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(s, c.Writer) + restServer.codec.Encode(s, c.Writer) } -func (this *RestServer) handleStorageAt(c *gin.Context) { +func (restServer *RestServer) handleStorageAt(c *gin.Context) { addr := c.MustGet("addrBts").([]byte) key := c.MustGet("keyBts").([]byte) - sa, err := this.pipe.Accounts().StorageAt(addr, key) + sa, err := restServer.pipe.Accounts().StorageAt(addr, key) if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(sa, c.Writer) + restServer.codec.Encode(sa, c.Writer) } // ********************************* Blockchain ********************************* -func (this *RestServer) handleBlockchainInfo(c *gin.Context) { - bci, err := this.pipe.Blockchain().Info() - if err != nil { - c.AbortWithError(500, err) - } +func (restServer *RestServer) handleBlockchainInfo(c *gin.Context) { + bci := pipes.BlockchainInfo(restServer.pipe) c.Writer.WriteHeader(200) - this.codec.Encode(bci, c.Writer) + restServer.codec.Encode(bci, c.Writer) } -func (this *RestServer) handleGenesisHash(c *gin.Context) { - gh, err := this.pipe.Blockchain().GenesisHash() - if err != nil { - c.AbortWithError(500, err) - } +func (restServer *RestServer) handleGenesisHash(c *gin.Context) { + gh := restServer.pipe.GenesisHash() c.Writer.WriteHeader(200) - this.codec.Encode(&core_types.GenesisHash{gh}, c.Writer) + restServer.codec.Encode(&core_types.GenesisHash{gh}, c.Writer) } -func (this *RestServer) handleChainId(c *gin.Context) { - cId, err := this.pipe.Blockchain().ChainId() - if err != nil { - c.AbortWithError(500, err) - } +func (restServer *RestServer) handleChainId(c *gin.Context) { + cId := restServer.pipe.Blockchain().ChainId() c.Writer.WriteHeader(200) - this.codec.Encode(&core_types.ChainId{cId}, c.Writer) + restServer.codec.Encode(&core_types.ChainId{cId}, c.Writer) } -func (this *RestServer) handleLatestBlockHeight(c *gin.Context) { - lbh, err := this.pipe.Blockchain().LatestBlockHeight() - if err != nil { - c.AbortWithError(500, err) - } +func (restServer *RestServer) handleLatestBlockHeight(c *gin.Context) { + lbh := restServer.pipe.Blockchain().Height() c.Writer.WriteHeader(200) - this.codec.Encode(&core_types.LatestBlockHeight{lbh}, c.Writer) + restServer.codec.Encode(&core_types.LatestBlockHeight{lbh}, c.Writer) } -func (this *RestServer) handleLatestBlock(c *gin.Context) { - lb, err := this.pipe.Blockchain().LatestBlock() - if err != nil { - c.AbortWithError(500, err) - } +func (restServer *RestServer) handleLatestBlock(c *gin.Context) { + latestHeight := restServer.pipe.Blockchain().Height() + lb := restServer.pipe.Blockchain().Block(latestHeight) c.Writer.WriteHeader(200) - this.codec.Encode(lb, c.Writer) + restServer.codec.Encode(lb, c.Writer) } -func (this *RestServer) handleBlocks(c *gin.Context) { +func (restServer *RestServer) handleBlocks(c *gin.Context) { var filters []*event.FilterData fs, exists := c.Get("filters") if exists { filters = fs.([]*event.FilterData) } - blocks, err := this.pipe.Blockchain().Blocks(filters) + blocks, err := blockchain.FilterBlocks(restServer.pipe.Blockchain(), + restServer.filterFactory, filters) + if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(blocks, c.Writer) + restServer.codec.Encode(blocks, c.Writer) } -func (this *RestServer) handleBlock(c *gin.Context) { +func (restServer *RestServer) handleBlock(c *gin.Context) { height := c.MustGet("height").(int) - block, err := this.pipe.Blockchain().Block(height) - if err != nil { - c.AbortWithError(500, err) - } + block := restServer.pipe.Blockchain().Block(height) c.Writer.WriteHeader(200) - this.codec.Encode(block, c.Writer) + restServer.codec.Encode(block, c.Writer) } // ********************************* Consensus ********************************* -func (this *RestServer) handleConsensusState(c *gin.Context) { - - cs, err := this.pipe.Consensus().State() - if err != nil { - c.AbortWithError(500, err) - } +func (restServer *RestServer) handleConsensusState(c *gin.Context) { + // TODO: [Silas] erisDbMethods has not implemented this since the refactor + // core_types.FromRoundState() will do it, but only if we have access to + // Tendermint's RonudState.. + cs := &core_types.ConsensusState{} c.Writer.WriteHeader(200) - this.codec.Encode(cs, c.Writer) + restServer.codec.Encode(cs, c.Writer) } -func (this *RestServer) handleValidatorList(c *gin.Context) { - vl, err := this.pipe.Consensus().Validators() - if err != nil { - c.AbortWithError(500, err) - } +func (restServer *RestServer) handleValidatorList(c *gin.Context) { + // TODO: [Silas] erisDbMethods has not implemented this since the refactor + vl := &core_types.ValidatorList{} c.Writer.WriteHeader(200) - this.codec.Encode(vl, c.Writer) + restServer.codec.Encode(vl, c.Writer) } // ********************************* Events ********************************* -func (this *RestServer) handleEventSubscribe(c *gin.Context) { +func (restServer *RestServer) handleEventSubscribe(c *gin.Context) { param := &EventIdParam{} - errD := this.codec.Decode(param, c.Request.Body) + errD := restServer.codec.Decode(param, c.Request.Body) if errD != nil { c.AbortWithError(500, errD) } - subId, err := this.eventSubs.Add(param.EventId) + subId, err := restServer.eventSubs.Add(param.EventId) if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(&event.EventSub{subId}, c.Writer) + restServer.codec.Encode(&event.EventSub{subId}, c.Writer) } -func (this *RestServer) handleEventPoll(c *gin.Context) { +func (restServer *RestServer) handleEventPoll(c *gin.Context) { subId := c.MustGet("id").(string) - data, err := this.eventSubs.Poll(subId) + data, err := restServer.eventSubs.Poll(subId) if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(&event.PollResponse{data}, c.Writer) + restServer.codec.Encode(&event.PollResponse{data}, c.Writer) } -func (this *RestServer) handleEventUnsubscribe(c *gin.Context) { +func (restServer *RestServer) handleEventUnsubscribe(c *gin.Context) { subId := c.MustGet("id").(string) - err := this.eventSubs.Remove(subId) + err := restServer.eventSubs.Remove(subId) if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(&event.EventUnsub{true}, c.Writer) + restServer.codec.Encode(&event.EventUnsub{true}, c.Writer) } // ********************************* NameReg ********************************* -func (this *RestServer) handleNameRegEntries(c *gin.Context) { +func (restServer *RestServer) handleNameRegEntries(c *gin.Context) { var filters []*event.FilterData fs, exists := c.Get("filters") if exists { filters = fs.([]*event.FilterData) } - entries, err := this.pipe.NameReg().Entries(filters) + entries, err := restServer.pipe.NameReg().Entries(filters) if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(entries, c.Writer) + restServer.codec.Encode(entries, c.Writer) } -func (this *RestServer) handleNameRegEntry(c *gin.Context) { +func (restServer *RestServer) handleNameRegEntry(c *gin.Context) { name := c.MustGet("name").(string) - entry, err := this.pipe.NameReg().Entry(name) + entry, err := restServer.pipe.NameReg().Entry(name) if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(entry, c.Writer) + restServer.codec.Encode(entry, c.Writer) } // ********************************* Network ********************************* -func (this *RestServer) handleNetworkInfo(c *gin.Context) { - nInfo, err := this.pipe.Net().Info() +func (restServer *RestServer) handleNetworkInfo(c *gin.Context) { + nInfo, err := restServer.pipe.Net().Info() if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(nInfo, c.Writer) + restServer.codec.Encode(nInfo, c.Writer) } -func (this *RestServer) handleClientVersion(c *gin.Context) { - version, err := this.pipe.Net().ClientVersion() +func (restServer *RestServer) handleClientVersion(c *gin.Context) { + version, err := restServer.pipe.Net().ClientVersion() if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(&core_types.ClientVersion{version}, c.Writer) + restServer.codec.Encode(&core_types.ClientVersion{version}, c.Writer) } -func (this *RestServer) handleMoniker(c *gin.Context) { - moniker, err := this.pipe.Net().Moniker() +func (restServer *RestServer) handleMoniker(c *gin.Context) { + moniker, err := restServer.pipe.Net().Moniker() if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(&core_types.Moniker{moniker}, c.Writer) + restServer.codec.Encode(&core_types.Moniker{moniker}, c.Writer) } -func (this *RestServer) handleListening(c *gin.Context) { - listening, err := this.pipe.Net().Listening() +func (restServer *RestServer) handleListening(c *gin.Context) { + listening, err := restServer.pipe.Net().Listening() if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(&core_types.Listening{listening}, c.Writer) + restServer.codec.Encode(&core_types.Listening{listening}, c.Writer) } -func (this *RestServer) handleListeners(c *gin.Context) { - listeners, err := this.pipe.Net().Listeners() +func (restServer *RestServer) handleListeners(c *gin.Context) { + listeners, err := restServer.pipe.Net().Listeners() if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(&core_types.Listeners{listeners}, c.Writer) + restServer.codec.Encode(&core_types.Listeners{listeners}, c.Writer) } -func (this *RestServer) handlePeers(c *gin.Context) { - peers, err := this.pipe.Net().Peers() +func (restServer *RestServer) handlePeers(c *gin.Context) { + peers, err := restServer.pipe.Net().Peers() if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(peers, c.Writer) + restServer.codec.Encode(peers, c.Writer) } -func (this *RestServer) handlePeer(c *gin.Context) { +func (restServer *RestServer) handlePeer(c *gin.Context) { address := c.MustGet("address").(string) - peer, err := this.pipe.Net().Peer(address) + peer, err := restServer.pipe.Net().Peer(address) if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(peer, c.Writer) + restServer.codec.Encode(peer, c.Writer) } // ********************************* Transactions ********************************* -func (this *RestServer) handleBroadcastTx(c *gin.Context) { +func (restServer *RestServer) handleBroadcastTx(c *gin.Context) { param := &txs.CallTx{} - errD := this.codec.Decode(param, c.Request.Body) + errD := restServer.codec.Decode(param, c.Request.Body) if errD != nil { c.AbortWithError(500, errD) } - receipt, err := this.pipe.Transactor().BroadcastTx(param) + receipt, err := restServer.pipe.Transactor().BroadcastTx(param) if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(receipt, c.Writer) + restServer.codec.Encode(receipt, c.Writer) } -func (this *RestServer) handleUnconfirmedTxs(c *gin.Context) { +func (restServer *RestServer) handleUnconfirmedTxs(c *gin.Context) { - txs, err := this.pipe.Transactor().UnconfirmedTxs() + txs, err := restServer.pipe.Transactor().UnconfirmedTxs() if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(txs, c.Writer) + restServer.codec.Encode(txs, c.Writer) } -func (this *RestServer) handleCall(c *gin.Context) { +func (restServer *RestServer) handleCall(c *gin.Context) { param := &CallParam{} - errD := this.codec.Decode(param, c.Request.Body) + errD := restServer.codec.Decode(param, c.Request.Body) if errD != nil { c.AbortWithError(500, errD) } - call, err := this.pipe.Transactor().Call(param.From, param.Address, param.Data) + call, err := restServer.pipe.Transactor().Call(param.From, param.Address, param.Data) if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(call, c.Writer) + restServer.codec.Encode(call, c.Writer) } -func (this *RestServer) handleCallCode(c *gin.Context) { +func (restServer *RestServer) handleCallCode(c *gin.Context) { param := &CallCodeParam{} - errD := this.codec.Decode(param, c.Request.Body) + errD := restServer.codec.Decode(param, c.Request.Body) if errD != nil { c.AbortWithError(500, errD) } - call, err := this.pipe.Transactor().CallCode(param.From, param.Code, param.Data) + call, err := restServer.pipe.Transactor().CallCode(param.From, param.Code, param.Data) if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(call, c.Writer) + restServer.codec.Encode(call, c.Writer) } -func (this *RestServer) handleTransact(c *gin.Context) { +func (restServer *RestServer) handleTransact(c *gin.Context) { _, hold := c.Get("hold") param := &TransactParam{} - errD := this.codec.Decode(param, c.Request.Body) + errD := restServer.codec.Decode(param, c.Request.Body) if errD != nil { c.AbortWithError(500, errD) } if hold { - res, err := this.pipe.Transactor().TransactAndHold(param.PrivKey, param.Address, param.Data, param.GasLimit, param.Fee) + res, err := restServer.pipe.Transactor().TransactAndHold(param.PrivKey, param.Address, param.Data, param.GasLimit, param.Fee) if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(res, c.Writer) + restServer.codec.Encode(res, c.Writer) } else { - receipt, err := this.pipe.Transactor().Transact(param.PrivKey, param.Address, param.Data, param.GasLimit, param.Fee) + receipt, err := restServer.pipe.Transactor().Transact(param.PrivKey, param.Address, param.Data, param.GasLimit, param.Fee) if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(receipt, c.Writer) + restServer.codec.Encode(receipt, c.Writer) } } -func (this *RestServer) handleTransactNameReg(c *gin.Context) { +func (restServer *RestServer) handleTransactNameReg(c *gin.Context) { param := &TransactNameRegParam{} - errD := this.codec.Decode(param, c.Request.Body) + errD := restServer.codec.Decode(param, c.Request.Body) if errD != nil { c.AbortWithError(500, errD) } - receipt, err := this.pipe.Transactor().TransactNameReg(param.PrivKey, param.Name, param.Data, param.Amount, param.Fee) + receipt, err := restServer.pipe.Transactor().TransactNameReg(param.PrivKey, param.Name, param.Data, param.Amount, param.Fee) if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(receipt, c.Writer) + restServer.codec.Encode(receipt, c.Writer) } -func (this *RestServer) handleSignTx(c *gin.Context) { +func (restServer *RestServer) handleSignTx(c *gin.Context) { param := &SignTxParam{} - errD := this.codec.Decode(param, c.Request.Body) + errD := restServer.codec.Decode(param, c.Request.Body) if errD != nil { c.AbortWithError(500, errD) } - tx, err := this.pipe.Transactor().SignTx(param.Tx, param.PrivAccounts) + tx, err := restServer.pipe.Transactor().SignTx(param.Tx, param.PrivAccounts) if err != nil { c.AbortWithError(500, err) } c.Writer.WriteHeader(200) - this.codec.Encode(tx, c.Writer) + restServer.codec.Encode(tx, c.Writer) } // ********************************* Middleware ********************************* @@ -601,7 +591,7 @@ func toFilterData(field, stmt string) (*event.FilterData, *event.FilterData, err } // Simple routine based on string splitting. TODO add quoted range query. if stmt[0] == '>' || stmt[0] == '<' || stmt[0] == '=' || stmt[0] == '!' { - // This means a normal operator. If one character then stop, otherwise + // restServer means a normal operator. If one character then stop, otherwise // peek at next and check if it's a "=". if len(stmt) == 1 { @@ -614,7 +604,7 @@ func toFilterData(field, stmt string) (*event.FilterData, *event.FilterData, err } else { // Either we have a range query here or a malformed query. rng := strings.Split(stmt, "..") - // This is for when there is no op, but the value is not empty. + // restServer is for when there is no op, but the value is not empty. if len(rng) == 1 { return &event.FilterData{field, "==", stmt}, nil, nil } diff --git a/rpc/v0/wsService.go b/rpc/v0/wsService.go index fdd48de0ed8f6a588fc3dd6e64f315328456cc8f..35705ed39c179ded02944c931580f04e57d51d96 100644 --- a/rpc/v0/wsService.go +++ b/rpc/v0/wsService.go @@ -24,7 +24,7 @@ type ErisDbWsService struct { func NewErisDbWsService(codec rpc.Codec, pipe definitions.Pipe) server.WebSocketService { tmwss := &ErisDbWsService{codec: codec, pipe: pipe} - mtds := &ErisDbMethods{codec, pipe} + mtds := NewErisDbMethods(codec, pipe) dhMap := mtds.getMethods() // Events diff --git a/test/mock/pipe.go b/test/mock/pipe.go index 9410d073d6b5259a7e0c3ab43a91c696d4abed0b..213bc6907a0da482acbbbcdc8fe3659b8e37745e 100644 --- a/test/mock/pipe.go +++ b/test/mock/pipe.go @@ -86,12 +86,12 @@ func (this *MockPipe) GetApplication() manager_types.Application { return nil } -func (this *MockPipe) SetConsensusEngine(_ definitions.ConsensusEngine) error { +func (this *MockPipe) SetConsensusEngine(_ definitions.Consensus) error { // TODO: [ben] mock consensus engine return nil } -func (this *MockPipe) GetConsensusEngine() definitions.ConsensusEngine { +func (this *MockPipe) GetConsensusEngine() definitions.Consensus { return nil }