diff --git a/cmd/sim_txs/main.go b/cmd/sim_txs/main.go index 1e928c0e..6946dfb1 100644 --- a/cmd/sim_txs/main.go +++ b/cmd/sim_txs/main.go @@ -9,6 +9,7 @@ import ( . "github.com/tendermint/tendermint/common" "github.com/tendermint/tendermint/rpc/client" ctypes "github.com/tendermint/tendermint/rpc/core/types" + cclient "github.com/tendermint/tendermint/rpc/core_client" "github.com/tendermint/tendermint/types" ) @@ -75,7 +76,7 @@ func main() { sendTx := makeRandomTransaction(10, rootAccount.Sequence+1, root, 2, accounts) fmt.Println(sendTx) - wsClient := rpcclient.NewWSClient("ws://" + remote + "/websocket") + wsClient := cclient.NewWSClient("ws://" + remote + "/websocket") _, err = wsClient.Start() if err != nil { Exit(Fmt("Failed to establish websocket connection: %v", err)) diff --git a/cmd/tendermint/gen_validator.go b/cmd/tendermint/gen_validator.go index e71795b6..e0e58e34 100644 --- a/cmd/tendermint/gen_validator.go +++ b/cmd/tendermint/gen_validator.go @@ -3,13 +3,13 @@ package main import ( "fmt" + "github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/wire" - sm "github.com/tendermint/tendermint/state" ) func gen_validator() { - privValidator := sm.GenPrivValidator() + privValidator := types.GenPrivValidator() privValidatorJSONBytes := wire.JSONBytes(privValidator) fmt.Printf(`Generated a new validator! Paste the following JSON into your %v file diff --git a/cmd/tendermint/reset_priv_validator.go b/cmd/tendermint/reset_priv_validator.go index 3a0c46d5..37f33d79 100644 --- a/cmd/tendermint/reset_priv_validator.go +++ b/cmd/tendermint/reset_priv_validator.go @@ -3,24 +3,24 @@ package main import ( "os" - sm "github.com/tendermint/tendermint/state" + "github.com/tendermint/tendermint/types" ) // NOTE: this is totally unsafe. // it's only suitable for testnets. func reset_priv_validator() { // Get PrivValidator - var privValidator *sm.PrivValidator + var privValidator *types.PrivValidator privValidatorFile := config.GetString("priv_validator_file") if _, err := os.Stat(privValidatorFile); err == nil { - privValidator = sm.LoadPrivValidator(privValidatorFile) + privValidator = types.LoadPrivValidator(privValidatorFile) privValidator.LastHeight = 0 privValidator.LastRound = 0 privValidator.LastStep = 0 privValidator.Save() log.Notice("Reset PrivValidator", "file", privValidatorFile) } else { - privValidator = sm.GenPrivValidator() + privValidator = types.GenPrivValidator() privValidator.SetFile(privValidatorFile) privValidator.Save() log.Notice("Generated PrivValidator", "file", privValidatorFile) diff --git a/common/os.go b/common/os.go index 5cdfd10a..efd2a55a 100644 --- a/common/os.go +++ b/common/os.go @@ -198,3 +198,11 @@ func (af *AutoFile) openFile() error { af.file = file return nil } + +func Tempfile(prefix string) (*os.File, string) { + file, err := ioutil.TempFile("", prefix) + if err != nil { + PanicCrisis(err) + } + return file, file.Name() +} diff --git a/config/tendermint/config.go b/config/tendermint/config.go index 759eb741..b9af1446 100644 --- a/config/tendermint/config.go +++ b/config/tendermint/config.go @@ -67,6 +67,7 @@ func GetConfig(rootDir string) cfg.Config { mapConfig.SetDefault("node_laddr", "0.0.0.0:46656") // mapConfig.SetDefault("seeds", "goldenalchemist.chaintest.net:46656") mapConfig.SetDefault("fast_sync", true) + mapConfig.SetDefault("skip_upnp", false) mapConfig.SetDefault("addrbook_file", rootDir+"/addrbook.json") mapConfig.SetDefault("priv_validator_file", rootDir+"/priv_validator.json") mapConfig.SetDefault("db_backend", "leveldb") diff --git a/config/tendermint_test/config.go b/config/tendermint_test/config.go index c208dc23..5d8d0935 100644 --- a/config/tendermint_test/config.go +++ b/config/tendermint_test/config.go @@ -68,6 +68,7 @@ func GetConfig(rootDir string) cfg.Config { mapConfig.SetDefault("moniker", "anonymous") mapConfig.SetDefault("node_laddr", "0.0.0.0:36656") mapConfig.SetDefault("fast_sync", false) + mapConfig.SetDefault("skip_upnp", true) mapConfig.SetDefault("addrbook_file", rootDir+"/addrbook.json") mapConfig.SetDefault("priv_validator_file", rootDir+"/priv_validator.json") mapConfig.SetDefault("db_backend", "memdb") diff --git a/consensus/height_vote_set.go b/consensus/height_vote_set.go index 279bf547..795b1eb2 100644 --- a/consensus/height_vote_set.go +++ b/consensus/height_vote_set.go @@ -5,13 +5,12 @@ import ( "sync" . "github.com/tendermint/tendermint/common" - sm "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/types" ) type RoundVoteSet struct { - Prevotes *VoteSet - Precommits *VoteSet + Prevotes *types.VoteSet + Precommits *types.VoteSet } /* @@ -28,7 +27,7 @@ peer to prevent abuse. */ type HeightVoteSet struct { height int - valSet *sm.ValidatorSet + valSet *types.ValidatorSet mtx sync.Mutex round int // max tracked round @@ -36,7 +35,7 @@ type HeightVoteSet struct { peerCatchupRounds map[string]int // keys: peer.Key; values: round } -func NewHeightVoteSet(height int, valSet *sm.ValidatorSet) *HeightVoteSet { +func NewHeightVoteSet(height int, valSet *types.ValidatorSet) *HeightVoteSet { hvs := &HeightVoteSet{ height: height, valSet: valSet, @@ -79,8 +78,8 @@ func (hvs *HeightVoteSet) addRound(round int) { PanicSanity("addRound() for an existing round") } log.Info("addRound(round)", "round", round) - prevotes := NewVoteSet(hvs.height, round, types.VoteTypePrevote, hvs.valSet) - precommits := NewVoteSet(hvs.height, round, types.VoteTypePrecommit, hvs.valSet) + prevotes := types.NewVoteSet(hvs.height, round, types.VoteTypePrevote, hvs.valSet) + precommits := types.NewVoteSet(hvs.height, round, types.VoteTypePrecommit, hvs.valSet) hvs.roundVoteSets[round] = RoundVoteSet{ Prevotes: prevotes, Precommits: precommits, @@ -109,13 +108,13 @@ func (hvs *HeightVoteSet) AddByAddress(address []byte, vote *types.Vote, peerKey return } -func (hvs *HeightVoteSet) Prevotes(round int) *VoteSet { +func (hvs *HeightVoteSet) Prevotes(round int) *types.VoteSet { hvs.mtx.Lock() defer hvs.mtx.Unlock() return hvs.getVoteSet(round, types.VoteTypePrevote) } -func (hvs *HeightVoteSet) Precommits(round int) *VoteSet { +func (hvs *HeightVoteSet) Precommits(round int) *types.VoteSet { hvs.mtx.Lock() defer hvs.mtx.Unlock() return hvs.getVoteSet(round, types.VoteTypePrecommit) @@ -134,7 +133,7 @@ func (hvs *HeightVoteSet) POLRound() int { return -1 } -func (hvs *HeightVoteSet) getVoteSet(round int, type_ byte) *VoteSet { +func (hvs *HeightVoteSet) getVoteSet(round int, type_ byte) *types.VoteSet { log.Info("getVoteSet(round)", "round", round, "type", type_) rvs, ok := hvs.roundVoteSets[round] if !ok { diff --git a/consensus/reactor.go b/consensus/reactor.go index bc400985..be9cd01e 100644 --- a/consensus/reactor.go +++ b/consensus/reactor.go @@ -10,7 +10,6 @@ import ( bc "github.com/tendermint/tendermint/blockchain" . "github.com/tendermint/tendermint/common" - . "github.com/tendermint/tendermint/consensus/types" "github.com/tendermint/tendermint/events" "github.com/tendermint/tendermint/p2p" sm "github.com/tendermint/tendermint/state" @@ -187,7 +186,7 @@ func (conR *ConsensusReactor) Receive(chId byte, peer *p2p.Peer, msgBytes []byte switch msg := msg.(type) { case *VoteMessage: vote := msg.Vote - var validators *sm.ValidatorSet + var validators *types.ValidatorSet if rs.Height == vote.Height { validators = rs.Validators } else if rs.Height == vote.Height+1 { @@ -268,7 +267,7 @@ func (conR *ConsensusReactor) broadcastHasVoteMessage(vote *types.Vote, index in } // Sets our private validator account for signing votes. -func (conR *ConsensusReactor) SetPrivValidator(priv *sm.PrivValidator) { +func (conR *ConsensusReactor) SetPrivValidator(priv *types.PrivValidator) { conR.conS.SetPrivValidator(priv) } @@ -598,7 +597,7 @@ func (ps *PeerState) GetRoundState() *PeerRoundState { return &prs } -func (ps *PeerState) SetHasProposal(proposal *Proposal) { +func (ps *PeerState) SetHasProposal(proposal *types.Proposal) { ps.mtx.Lock() defer ps.mtx.Unlock() @@ -964,7 +963,7 @@ func (m *CommitStepMessage) String() string { //------------------------------------- type ProposalMessage struct { - Proposal *Proposal + Proposal *types.Proposal } func (m *ProposalMessage) String() string { diff --git a/consensus/state.go b/consensus/state.go index 5db6b41b..07843978 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -160,7 +160,6 @@ import ( acm "github.com/tendermint/tendermint/account" bc "github.com/tendermint/tendermint/blockchain" . "github.com/tendermint/tendermint/common" - . "github.com/tendermint/tendermint/consensus/types" "github.com/tendermint/tendermint/events" mempl "github.com/tendermint/tendermint/mempool" sm "github.com/tendermint/tendermint/state" @@ -231,16 +230,16 @@ type RoundState struct { Step RoundStepType StartTime time.Time CommitTime time.Time // Subjective time when +2/3 precommits for Block at Round were found - Validators *sm.ValidatorSet - Proposal *Proposal + Validators *types.ValidatorSet + Proposal *types.Proposal ProposalBlock *types.Block ProposalBlockParts *types.PartSet LockedRound int LockedBlock *types.Block LockedBlockParts *types.PartSet Votes *HeightVoteSet - LastCommit *VoteSet // Last precommits at Height-1 - LastValidators *sm.ValidatorSet + LastCommit *types.VoteSet // Last precommits at Height-1 + LastValidators *types.ValidatorSet } func (rs *RoundState) String() string { @@ -288,7 +287,7 @@ type ConsensusState struct { blockStore *bc.BlockStore mempoolReactor *mempl.MempoolReactor - privValidator *sm.PrivValidator + privValidator *types.PrivValidator newStepCh chan *RoundState mtx sync.Mutex @@ -322,7 +321,7 @@ func (cs *ConsensusState) reconstructLastCommit(state *sm.State) { if state.LastBlockHeight == 0 { return } - lastPrecommits := NewVoteSet(state.LastBlockHeight, 0, types.VoteTypePrecommit, state.LastBondedValidators) + lastPrecommits := types.NewVoteSet(state.LastBlockHeight, 0, types.VoteTypePrecommit, state.LastBondedValidators) seenValidation := cs.blockStore.LoadSeenValidation(state.LastBlockHeight) for idx, precommit := range seenValidation.Precommits { if precommit == nil { @@ -408,7 +407,7 @@ func (cs *ConsensusState) updateToState(state *sm.State, contiguous bool) { // Reset fields based on state. validators := state.BondedValidators height := state.LastBlockHeight + 1 // next desired block height - lastPrecommits := (*VoteSet)(nil) + lastPrecommits := (*types.VoteSet)(nil) if contiguous && cs.Votes != nil { if !cs.Votes.Precommits(cs.Round).HasTwoThirdsMajority() { PanicSanity("updateToState(state, true) called but last Precommit round didn't have +2/3") @@ -474,7 +473,7 @@ func (cs *ConsensusState) maybeRebond() { } } -func (cs *ConsensusState) SetPrivValidator(priv *sm.PrivValidator) { +func (cs *ConsensusState) SetPrivValidator(priv *types.PrivValidator) { cs.mtx.Lock() defer cs.mtx.Unlock() cs.privValidator = priv @@ -580,7 +579,7 @@ func (cs *ConsensusState) decideProposal(height int, round int) { } // Make proposal - proposal := NewProposal(height, round, blockParts.Header(), cs.Votes.POLRound()) + proposal := types.NewProposal(height, round, blockParts.Header(), cs.Votes.POLRound()) err := cs.privValidator.SignProposal(cs.state.ChainID, proposal) if err == nil { log.Notice("Signed and set proposal", "height", height, "round", round, "proposal", proposal) @@ -971,7 +970,7 @@ func (cs *ConsensusState) FinalizeCommit(height int) { //----------------------------------------------------------------------------- -func (cs *ConsensusState) SetProposal(proposal *Proposal) error { +func (cs *ConsensusState) SetProposal(proposal *types.Proposal) error { cs.mtx.Lock() defer cs.mtx.Unlock() @@ -1191,7 +1190,7 @@ func (cs *ConsensusState) signAddVote(type_ byte, hash []byte, header types.Part } // Save Block, save the +2/3 Commits we've seen -func (cs *ConsensusState) saveBlock(block *types.Block, blockParts *types.PartSet, commits *VoteSet) { +func (cs *ConsensusState) saveBlock(block *types.Block, blockParts *types.PartSet, commits *types.VoteSet) { // The proposal must be valid. if err := cs.stageBlock(block, blockParts); err != nil { @@ -1212,7 +1211,7 @@ func (cs *ConsensusState) saveBlock(block *types.Block, blockParts *types.PartSe // Fire off event go func(block *types.Block) { - cs.evsw.FireEvent(types.EventStringNewBlock(), block) + cs.evsw.FireEvent(types.EventStringNewBlock(), types.EventDataNewBlock{block}) cs.evc.Flush() }(block) diff --git a/consensus/test.go b/consensus/test.go index c105f156..a12c925c 100644 --- a/consensus/test.go +++ b/consensus/test.go @@ -1,15 +1,14 @@ package consensus import ( - "sort" - bc "github.com/tendermint/tendermint/blockchain" dbm "github.com/tendermint/tendermint/db" mempl "github.com/tendermint/tendermint/mempool" sm "github.com/tendermint/tendermint/state" + "github.com/tendermint/tendermint/types" ) -func randConsensusState() (*ConsensusState, []*sm.PrivValidator) { +func randConsensusState() (*ConsensusState, []*types.PrivValidator) { state, _, privValidators := sm.RandGenesisState(20, false, 1000, 10, false, 1000) blockStore := bc.NewBlockStore(dbm.NewMemDB()) mempool := mempl.NewMempool(state) @@ -17,16 +16,3 @@ func randConsensusState() (*ConsensusState, []*sm.PrivValidator) { cs := NewConsensusState(state, blockStore, mempoolReactor) return cs, privValidators } - -func randVoteSet(height int, round int, type_ byte, numValidators int, votingPower int64) (*VoteSet, *sm.ValidatorSet, []*sm.PrivValidator) { - vals := make([]*sm.Validator, numValidators) - privValidators := make([]*sm.PrivValidator, numValidators) - for i := 0; i < numValidators; i++ { - _, val, privValidator := sm.RandValidator(false, votingPower) - vals[i] = val - privValidators[i] = privValidator - } - valSet := sm.NewValidatorSet(vals) - sort.Sort(sm.PrivValidatorsByAddress(privValidators)) - return NewVoteSet(height, round, type_, valSet), valSet, privValidators -} diff --git a/crawler/crawl.go b/crawler/crawl.go index ac4665b2..b06073e4 100644 --- a/crawler/crawl.go +++ b/crawler/crawl.go @@ -5,12 +5,9 @@ import ( "time" . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/rpc/client" ctypes "github.com/tendermint/tendermint/rpc/core/types" - core "github.com/tendermint/tendermint/rpc/core_client" - "github.com/tendermint/tendermint/rpc/types" + cclient "github.com/tendermint/tendermint/rpc/core_client" "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/wire" ) const ( @@ -37,7 +34,7 @@ type Node struct { ChainID string BlockHeight int BlockHistory map[int]time.Time // when we saw each block - NetInfo *ctypes.ResponseNetInfo + NetInfo *ctypes.ResultNetInfo Validator bool @@ -50,7 +47,7 @@ func (n *Node) Address() string { } // Set the basic status and chain_id info for a node from RPC responses -func (n *Node) SetInfo(status *ctypes.ResponseStatus, netinfo *ctypes.ResponseNetInfo) { +func (n *Node) SetInfo(status *ctypes.ResultStatus, netinfo *ctypes.ResultNetInfo) { n.LastSeen = time.Now() n.ChainID = status.NodeInfo.ChainID n.BlockHeight = status.LatestBlockHeight @@ -60,15 +57,15 @@ func (n *Node) SetInfo(status *ctypes.ResponseStatus, netinfo *ctypes.ResponseNe // A node client is used to talk to a node over rpc and websockets type NodeClient struct { - rpc core.Client - ws *rpcclient.WSClient + rpc cclient.Client + ws *cclient.WSClient } // Create a new client for the node at the given addr func NewNodeClient(addr string) *NodeClient { return &NodeClient{ - rpc: core.NewClient("http://"+addr, "JSONRPC"), - ws: rpcclient.NewWSClient("ws://" + addr + "/events"), + rpc: cclient.NewClient("http://"+addr, "JSONRPC"), + ws: cclient.NewWSClient("ws://" + addr + "/events"), } } @@ -183,11 +180,8 @@ func (c *Crawler) readLoop(node *Node) { } } -func (c *Crawler) consumeMessage(eventMsg rpctypes.RPCEventResult, node *Node) error { - var block *types.Block - var err error - wire.ReadJSONObject(block, eventMsg.Data, &err) - +func (c *Crawler) consumeMessage(eventMsg ctypes.ResultEvent, node *Node) error { + block := eventMsg.Data.(*types.Block) node.LastSeen = time.Now() node.BlockHeight = block.Height node.BlockHistory[block.Height] = node.LastSeen diff --git a/events/event_cache.go b/events/event_cache.go index 3231fe0d..9f4f0804 100644 --- a/events/event_cache.go +++ b/events/event_cache.go @@ -1,5 +1,9 @@ package events +import ( + "github.com/tendermint/tendermint/types" +) + const ( eventsBufferSize = 1000 ) @@ -22,20 +26,20 @@ func NewEventCache(evsw Fireable) *EventCache { // a cached event type eventInfo struct { event string - msg interface{} + data types.EventData } // Cache an event to be fired upon finality. -func (evc *EventCache) FireEvent(event string, msg interface{}) { +func (evc *EventCache) FireEvent(event string, data interface{}) { // append to list - evc.events = append(evc.events, eventInfo{event, msg}) + evc.events = append(evc.events, eventInfo{event, data}) } // Fire events by running evsw.FireEvent on all cached events. Blocks. // Clears cached events func (evc *EventCache) Flush() { for _, ei := range evc.events { - evc.evsw.FireEvent(ei.event, ei.msg) + evc.evsw.FireEvent(ei.event, ei.data) } evc.events = make([]eventInfo, eventsBufferSize) } diff --git a/node/node.go b/node/node.go index aaa828f5..9a3d0597 100644 --- a/node/node.go +++ b/node/node.go @@ -21,6 +21,7 @@ import ( "github.com/tendermint/tendermint/rpc/core" "github.com/tendermint/tendermint/rpc/server" sm "github.com/tendermint/tendermint/state" + stypes "github.com/tendermint/tendermint/state/types" "github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/wire" ) @@ -37,8 +38,8 @@ type Node struct { mempoolReactor *mempl.MempoolReactor consensusState *consensus.ConsensusState consensusReactor *consensus.ConsensusReactor - privValidator *sm.PrivValidator - genDoc *sm.GenesisDoc + privValidator *types.PrivValidator + genDoc *stypes.GenesisDoc privKey acm.PrivKeyEd25519 } @@ -50,19 +51,19 @@ func NewNode() *Node { // Get State stateDB := dbm.GetDB("state") state := sm.LoadState(stateDB) - var genDoc *sm.GenesisDoc + var genDoc *stypes.GenesisDoc if state == nil { genDoc, state = sm.MakeGenesisStateFromFile(stateDB, config.GetString("genesis_file")) state.Save() // write the gendoc to db buf, n, err := new(bytes.Buffer), new(int64), new(error) wire.WriteJSON(genDoc, buf, n, err) - stateDB.Set(sm.GenDocKey, buf.Bytes()) + stateDB.Set(stypes.GenDocKey, buf.Bytes()) if *err != nil { Exit(Fmt("Unable to write gendoc to db: %v", err)) } } else { - genDocBytes := stateDB.Get(sm.GenDocKey) + genDocBytes := stateDB.Get(stypes.GenDocKey) err := new(error) wire.ReadJSONPtr(&genDoc, genDocBytes, err) if *err != nil { @@ -73,14 +74,14 @@ func NewNode() *Node { config.Set("chain_id", state.ChainID) // Get PrivValidator - var privValidator *sm.PrivValidator + var privValidator *types.PrivValidator privValidatorFile := config.GetString("priv_validator_file") if _, err := os.Stat(privValidatorFile); err == nil { - privValidator = sm.LoadPrivValidator(privValidatorFile) + privValidator = types.LoadPrivValidator(privValidatorFile) log.Notice("Loaded PrivValidator", "file", privValidatorFile, "privValidator", privValidator) } else { - privValidator = sm.GenPrivValidator() + privValidator = types.GenPrivValidator() privValidator.SetFile(privValidatorFile) privValidator.Save() log.Notice("Generated PrivValidator", "file", privValidatorFile) @@ -281,7 +282,7 @@ func makeNodeInfo(sw *p2p.Switch, privKey acm.PrivKeyEd25519) *types.NodeInfo { func RunNode() { // Create & start node n := NewNode() - l := p2p.NewDefaultListener("tcp", config.GetString("node_laddr"), false) + l := p2p.NewDefaultListener("tcp", config.GetString("node_laddr")) n.AddListener(l) err := n.Start() if err != nil { diff --git a/node/node_test.go b/node/node_test.go index 05f3ca22..a958c96c 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -11,7 +11,7 @@ import ( func TestNodeStartStop(t *testing.T) { // Create & start node n := NewNode() - l := p2p.NewDefaultListener("tcp", config.GetString("node_laddr"), false) + l := p2p.NewDefaultListener("tcp", config.GetString("node_laddr")) n.AddListener(l) n.Start() log.Notice("Started node", "nodeInfo", n.sw.NodeInfo()) diff --git a/consensus/types/config.go b/p2p/config.go similarity index 90% rename from consensus/types/config.go rename to p2p/config.go index 8366b36c..c9cbf126 100644 --- a/consensus/types/config.go +++ b/p2p/config.go @@ -1,4 +1,4 @@ -package consensus +package p2p import ( cfg "github.com/tendermint/tendermint/config" diff --git a/p2p/listener.go b/p2p/listener.go index 6a62f9ba..131d9695 100644 --- a/p2p/listener.go +++ b/p2p/listener.go @@ -46,7 +46,7 @@ func splitHostPort(addr string) (host string, port int) { return host, port } -func NewDefaultListener(protocol string, lAddr string, requireUPNPHairpin bool) Listener { +func NewDefaultListener(protocol string, lAddr string) Listener { // Local listen IP & port lAddrIP, lAddrPort := splitHostPort(lAddr) @@ -73,22 +73,12 @@ func NewDefaultListener(protocol string, lAddr string, requireUPNPHairpin bool) // Determine external address... var extAddr *NetAddress - // If the lAddrIP is INADDR_ANY, try UPnP - if lAddrIP == "" || lAddrIP == "0.0.0.0" { - if requireUPNPHairpin { - upnpCapabilities, err := upnp.Probe() - if err != nil { - log.Warn("Failed to probe UPNP", "error", err) - goto SKIP_UPNP - } - if !upnpCapabilities.Hairpin { - goto SKIP_UPNP - } + if !config.GetBool("skip_upnp") { + // If the lAddrIP is INADDR_ANY, try UPnP + if lAddrIP == "" || lAddrIP == "0.0.0.0" { + extAddr = getUPNPExternalAddress(lAddrPort, listenerPort) } - extAddr = getUPNPExternalAddress(lAddrPort, listenerPort) } -SKIP_UPNP: - // Otherwise just use the local address... if extAddr == nil { extAddr = getNaiveExternalAddress(listenerPort) diff --git a/p2p/switch_test.go b/p2p/switch_test.go index 68839135..b0381159 100644 --- a/p2p/switch_test.go +++ b/p2p/switch_test.go @@ -7,9 +7,10 @@ import ( "time" acm "github.com/tendermint/tendermint/account" - "github.com/tendermint/tendermint/wire" . "github.com/tendermint/tendermint/common" + _ "github.com/tendermint/tendermint/config/tendermint_test" "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/wire" ) type PeerMessage struct { @@ -97,7 +98,7 @@ func makeSwitchPair(t testing.TB, initSwitch func(*Switch) *Switch) (*Switch, *S s2.Start() // Create a listener for s1 - l := NewDefaultListener("tcp", ":8001", true) + l := NewDefaultListener("tcp", ":8001") // Dial the listener & add the connection to s2. lAddr := l.ExternalAddress() diff --git a/rpc/core/accounts.go b/rpc/core/accounts.go index 22032a3b..47dc8889 100644 --- a/rpc/core/accounts.go +++ b/rpc/core/accounts.go @@ -7,21 +7,21 @@ import ( ctypes "github.com/tendermint/tendermint/rpc/core/types" ) -func GenPrivAccount() (*acm.PrivAccount, error) { - return acm.GenPrivAccount(), nil +func GenPrivAccount() (*ctypes.ResultGenPrivAccount, error) { + return &ctypes.ResultGenPrivAccount{acm.GenPrivAccount()}, nil } // If the account is not known, returns nil, nil. -func GetAccount(address []byte) (*acm.Account, error) { +func GetAccount(address []byte) (*ctypes.ResultGetAccount, error) { cache := mempoolReactor.Mempool.GetCache() account := cache.GetAccount(address) if account == nil { return nil, nil } - return account, nil + return &ctypes.ResultGetAccount{account}, nil } -func GetStorage(address, key []byte) (*ctypes.ResponseGetStorage, error) { +func GetStorage(address, key []byte) (*ctypes.ResultGetStorage, error) { state := consensusState.GetState() account := state.GetAccount(address) if account == nil { @@ -32,12 +32,12 @@ func GetStorage(address, key []byte) (*ctypes.ResponseGetStorage, error) { _, value := storageTree.Get(LeftPadWord256(key).Bytes()) if value == nil { - return &ctypes.ResponseGetStorage{key, nil}, nil + return &ctypes.ResultGetStorage{key, nil}, nil } - return &ctypes.ResponseGetStorage{key, value.([]byte)}, nil + return &ctypes.ResultGetStorage{key, value.([]byte)}, nil } -func ListAccounts() (*ctypes.ResponseListAccounts, error) { +func ListAccounts() (*ctypes.ResultListAccounts, error) { var blockHeight int var accounts []*acm.Account state := consensusState.GetState() @@ -46,10 +46,10 @@ func ListAccounts() (*ctypes.ResponseListAccounts, error) { accounts = append(accounts, value.(*acm.Account)) return false }) - return &ctypes.ResponseListAccounts{blockHeight, accounts}, nil + return &ctypes.ResultListAccounts{blockHeight, accounts}, nil } -func DumpStorage(address []byte) (*ctypes.ResponseDumpStorage, error) { +func DumpStorage(address []byte) (*ctypes.ResultDumpStorage, error) { state := consensusState.GetState() account := state.GetAccount(address) if account == nil { @@ -63,5 +63,5 @@ func DumpStorage(address []byte) (*ctypes.ResponseDumpStorage, error) { key.([]byte), value.([]byte)}) return false }) - return &ctypes.ResponseDumpStorage{storageRoot, storageItems}, nil + return &ctypes.ResultDumpStorage{storageRoot, storageItems}, nil } diff --git a/rpc/core/blocks.go b/rpc/core/blocks.go index 4809bf54..427390a2 100644 --- a/rpc/core/blocks.go +++ b/rpc/core/blocks.go @@ -9,7 +9,7 @@ import ( //----------------------------------------------------------------------------- -func BlockchainInfo(minHeight, maxHeight int) (*ctypes.ResponseBlockchainInfo, error) { +func BlockchainInfo(minHeight, maxHeight int) (*ctypes.ResultBlockchainInfo, error) { if maxHeight == 0 { maxHeight = blockStore.Height() } else { @@ -26,12 +26,12 @@ func BlockchainInfo(minHeight, maxHeight int) (*ctypes.ResponseBlockchainInfo, e blockMetas = append(blockMetas, blockMeta) } - return &ctypes.ResponseBlockchainInfo{blockStore.Height(), blockMetas}, nil + return &ctypes.ResultBlockchainInfo{blockStore.Height(), blockMetas}, nil } //----------------------------------------------------------------------------- -func GetBlock(height int) (*ctypes.ResponseGetBlock, error) { +func GetBlock(height int) (*ctypes.ResultGetBlock, error) { if height == 0 { return nil, fmt.Errorf("Height must be greater than 0") } @@ -41,5 +41,5 @@ func GetBlock(height int) (*ctypes.ResponseGetBlock, error) { blockMeta := blockStore.LoadBlockMeta(height) block := blockStore.LoadBlock(height) - return &ctypes.ResponseGetBlock{blockMeta, block}, nil + return &ctypes.ResultGetBlock{blockMeta, block}, nil } diff --git a/rpc/core/consensus.go b/rpc/core/consensus.go index 17b87877..d6abcf72 100644 --- a/rpc/core/consensus.go +++ b/rpc/core/consensus.go @@ -1,32 +1,32 @@ package core import ( - "github.com/tendermint/tendermint/wire" cm "github.com/tendermint/tendermint/consensus" ctypes "github.com/tendermint/tendermint/rpc/core/types" - sm "github.com/tendermint/tendermint/state" + "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/wire" ) -func ListValidators() (*ctypes.ResponseListValidators, error) { +func ListValidators() (*ctypes.ResultListValidators, error) { var blockHeight int - var bondedValidators []*sm.Validator - var unbondingValidators []*sm.Validator + var bondedValidators []*types.Validator + var unbondingValidators []*types.Validator state := consensusState.GetState() blockHeight = state.LastBlockHeight - state.BondedValidators.Iterate(func(index int, val *sm.Validator) bool { + state.BondedValidators.Iterate(func(index int, val *types.Validator) bool { bondedValidators = append(bondedValidators, val) return false }) - state.UnbondingValidators.Iterate(func(index int, val *sm.Validator) bool { + state.UnbondingValidators.Iterate(func(index int, val *types.Validator) bool { unbondingValidators = append(unbondingValidators, val) return false }) - return &ctypes.ResponseListValidators{blockHeight, bondedValidators, unbondingValidators}, nil + return &ctypes.ResultListValidators{blockHeight, bondedValidators, unbondingValidators}, nil } -func DumpConsensusState() (*ctypes.ResponseDumpConsensusState, error) { +func DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) { roundState := consensusState.GetRoundState() peerRoundStates := []string{} for _, peer := range p2pSwitch.Peers().List() { @@ -36,5 +36,5 @@ func DumpConsensusState() (*ctypes.ResponseDumpConsensusState, error) { peerRoundStateStr := peer.Key + ":" + string(wire.JSONBytes(peerRoundState)) peerRoundStates = append(peerRoundStates, peerRoundStateStr) } - return &ctypes.ResponseDumpConsensusState{roundState.String(), peerRoundStates}, nil + return &ctypes.ResultDumpConsensusState{roundState.String(), peerRoundStates}, nil } diff --git a/rpc/core/mempool.go b/rpc/core/mempool.go index 919e13df..eaf1d5c6 100644 --- a/rpc/core/mempool.go +++ b/rpc/core/mempool.go @@ -10,7 +10,7 @@ import ( //----------------------------------------------------------------------------- // Note: tx must be signed -func BroadcastTx(tx types.Tx) (*ctypes.Receipt, error) { +func BroadcastTx(tx types.Tx) (*ctypes.ResultBroadcastTx, error) { err := mempoolReactor.BroadcastTx(tx) if err != nil { return nil, fmt.Errorf("Error broadcasting transaction: %v", err) @@ -26,9 +26,9 @@ func BroadcastTx(tx types.Tx) (*ctypes.Receipt, error) { contractAddr = state.NewContractAddress(callTx.Input.Address, callTx.Input.Sequence) } } - return &ctypes.Receipt{txHash, createsContract, contractAddr}, nil + return &ctypes.ResultBroadcastTx{ctypes.Receipt{txHash, createsContract, contractAddr}}, nil } -func ListUnconfirmedTxs() ([]types.Tx, error) { - return mempoolReactor.Mempool.GetProposalTxs(), nil +func ListUnconfirmedTxs() (*ctypes.ResultListUnconfirmedTxs, error) { + return &ctypes.ResultListUnconfirmedTxs{mempoolReactor.Mempool.GetProposalTxs()}, nil } diff --git a/rpc/core/names.go b/rpc/core/names.go index 01c7cef1..318beaaf 100644 --- a/rpc/core/names.go +++ b/rpc/core/names.go @@ -7,16 +7,16 @@ import ( "github.com/tendermint/tendermint/types" ) -func GetName(name string) (*types.NameRegEntry, error) { +func GetName(name string) (*ctypes.ResultGetName, error) { st := consensusState.GetState() // performs a copy entry := st.GetNameRegEntry(name) if entry == nil { return nil, fmt.Errorf("Name %s not found", name) } - return entry, nil + return &ctypes.ResultGetName{entry}, nil } -func ListNames() (*ctypes.ResponseListNames, error) { +func ListNames() (*ctypes.ResultListNames, error) { var blockHeight int var names []*types.NameRegEntry state := consensusState.GetState() @@ -25,5 +25,5 @@ func ListNames() (*ctypes.ResponseListNames, error) { names = append(names, value.(*types.NameRegEntry)) return false }) - return &ctypes.ResponseListNames{blockHeight, names}, nil + return &ctypes.ResultListNames{blockHeight, names}, nil } diff --git a/rpc/core/net.go b/rpc/core/net.go index ef0cc834..7ce50312 100644 --- a/rpc/core/net.go +++ b/rpc/core/net.go @@ -12,7 +12,7 @@ import ( // cache the genesis state var genesisState *sm.State -func Status() (*ctypes.ResponseStatus, error) { +func Status() (*ctypes.ResultStatus, error) { db := dbm.NewMemDB() if genesisState == nil { genesisState = sm.MakeGenesisState(db, genDoc) @@ -30,7 +30,7 @@ func Status() (*ctypes.ResponseStatus, error) { latestBlockTime = latestBlockMeta.Header.Time.UnixNano() } - return &ctypes.ResponseStatus{ + return &ctypes.ResultStatus{ NodeInfo: p2pSwitch.NodeInfo(), GenesisHash: genesisHash, PubKey: privValidator.PubKey, @@ -41,7 +41,7 @@ func Status() (*ctypes.ResponseStatus, error) { //----------------------------------------------------------------------------- -func NetInfo() (*ctypes.ResponseNetInfo, error) { +func NetInfo() (*ctypes.ResultNetInfo, error) { listening := p2pSwitch.IsListening() listeners := []string{} for _, listener := range p2pSwitch.Listeners() { @@ -54,7 +54,7 @@ func NetInfo() (*ctypes.ResponseNetInfo, error) { IsOutbound: peer.IsOutbound(), }) } - return &ctypes.ResponseNetInfo{ + return &ctypes.ResultNetInfo{ Listening: listening, Listeners: listeners, Peers: peers, @@ -63,6 +63,6 @@ func NetInfo() (*ctypes.ResponseNetInfo, error) { //----------------------------------------------------------------------------- -func Genesis() (*sm.GenesisDoc, error) { - return genDoc, nil +func Genesis() (*ctypes.ResultGenesis, error) { + return &ctypes.ResultGenesis{genDoc}, nil } diff --git a/rpc/core/pipe.go b/rpc/core/pipe.go index aba30474..1cad8013 100644 --- a/rpc/core/pipe.go +++ b/rpc/core/pipe.go @@ -5,7 +5,8 @@ import ( "github.com/tendermint/tendermint/consensus" mempl "github.com/tendermint/tendermint/mempool" "github.com/tendermint/tendermint/p2p" - "github.com/tendermint/tendermint/state" + stypes "github.com/tendermint/tendermint/state/types" + "github.com/tendermint/tendermint/types" ) var blockStore *bc.BlockStore @@ -13,8 +14,8 @@ var consensusState *consensus.ConsensusState var consensusReactor *consensus.ConsensusReactor var mempoolReactor *mempl.MempoolReactor var p2pSwitch *p2p.Switch -var privValidator *state.PrivValidator -var genDoc *state.GenesisDoc // cache the genesis structure +var privValidator *types.PrivValidator +var genDoc *stypes.GenesisDoc // cache the genesis structure func SetBlockStore(bs *bc.BlockStore) { blockStore = bs @@ -36,10 +37,10 @@ func SetSwitch(sw *p2p.Switch) { p2pSwitch = sw } -func SetPrivValidator(pv *state.PrivValidator) { +func SetPrivValidator(pv *types.PrivValidator) { privValidator = pv } -func SetGenDoc(doc *state.GenesisDoc) { +func SetGenDoc(doc *stypes.GenesisDoc) { genDoc = doc } diff --git a/rpc/core/txs.go b/rpc/core/txs.go index a45fd997..073b6665 100644 --- a/rpc/core/txs.go +++ b/rpc/core/txs.go @@ -24,7 +24,7 @@ func toVMAccount(acc *acm.Account) *vm.Account { // Run a contract's code on an isolated and unpersisted state // Cannot be used to create new contracts -func Call(fromAddress, toAddress, data []byte) (*ctypes.ResponseCall, error) { +func Call(fromAddress, toAddress, data []byte) (*ctypes.ResultCall, error) { st := consensusState.GetState() // performs a copy cache := state.NewBlockCache(st) outAcc := cache.GetAccount(toAddress) @@ -47,12 +47,12 @@ func Call(fromAddress, toAddress, data []byte) (*ctypes.ResponseCall, error) { if err != nil { return nil, err } - return &ctypes.ResponseCall{Return: ret}, nil + return &ctypes.ResultCall{Return: ret}, nil } // Run the given code on an isolated and unpersisted state // Cannot be used to create new contracts -func CallCode(fromAddress, code, data []byte) (*ctypes.ResponseCall, error) { +func CallCode(fromAddress, code, data []byte) (*ctypes.ResultCall, error) { st := consensusState.GetState() // performs a copy cache := mempoolReactor.Mempool.GetCache() @@ -72,12 +72,12 @@ func CallCode(fromAddress, code, data []byte) (*ctypes.ResponseCall, error) { if err != nil { return nil, err } - return &ctypes.ResponseCall{Return: ret}, nil + return &ctypes.ResultCall{Return: ret}, nil } //----------------------------------------------------------------------------- -func SignTx(tx types.Tx, privAccounts []*acm.PrivAccount) (types.Tx, error) { +func SignTx(tx types.Tx, privAccounts []*acm.PrivAccount) (*ctypes.ResultSignTx, error) { // more checks? for i, privAccount := range privAccounts { @@ -112,5 +112,5 @@ func SignTx(tx types.Tx, privAccounts []*acm.PrivAccount) (types.Tx, error) { rebondTx := tx.(*types.RebondTx) rebondTx.Signature = privAccounts[0].Sign(config.GetString("chain_id"), rebondTx).(acm.SignatureEd25519) } - return tx, nil + return &ctypes.ResultSignTx{tx}, nil } diff --git a/rpc/core/types/responses.go b/rpc/core/types/responses.go index be428f7e..4fb43d42 100644 --- a/rpc/core/types/responses.go +++ b/rpc/core/types/responses.go @@ -2,53 +2,48 @@ package core_types import ( acm "github.com/tendermint/tendermint/account" - sm "github.com/tendermint/tendermint/state" + stypes "github.com/tendermint/tendermint/state/types" "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/wire" ) -type ResponseGetStorage struct { +type ResultGetStorage struct { Key []byte `json:"key"` Value []byte `json:"value"` } -type ResponseCall struct { +type ResultCall struct { Return []byte `json:"return"` GasUsed int64 `json:"gas_used"` // TODO ... } -type ResponseListAccounts struct { +type ResultListAccounts struct { BlockHeight int `json:"block_height"` Accounts []*acm.Account `json:"accounts"` } +type ResultDumpStorage struct { + StorageRoot []byte `json:"storage_root"` + StorageItems []StorageItem `json:"storage_items"` +} + type StorageItem struct { Key []byte `json:"key"` Value []byte `json:"value"` } -type ResponseDumpStorage struct { - StorageRoot []byte `json:"storage_root"` - StorageItems []StorageItem `json:"storage_items"` -} - -type ResponseBlockchainInfo struct { +type ResultBlockchainInfo struct { LastHeight int `json:"last_height"` BlockMetas []*types.BlockMeta `json:"block_metas"` } -type ResponseGetBlock struct { +type ResultGetBlock struct { BlockMeta *types.BlockMeta `json:"block_meta"` Block *types.Block `json:"block"` } -type Receipt struct { - TxHash []byte `json:"tx_hash"` - CreatesContract uint8 `json:"creates_contract"` - ContractAddr []byte `json:"contract_addr"` -} - -type ResponseStatus struct { +type ResultStatus struct { NodeInfo *types.NodeInfo `json:"node_info"` GenesisHash []byte `json:"genesis_hash"` PubKey acm.PubKey `json:"pub_key"` @@ -57,7 +52,7 @@ type ResponseStatus struct { LatestBlockTime int64 `json:"latest_block_time"` // nano } -type ResponseNetInfo struct { +type ResultNetInfo struct { Listening bool `json:"listening"` Listeners []string `json:"listeners"` Peers []Peer `json:"peers"` @@ -68,26 +63,115 @@ type Peer struct { IsOutbound bool `json:"is_outbound"` } -type ResponseListValidators struct { - BlockHeight int `json:"block_height"` - BondedValidators []*sm.Validator `json:"bonded_validators"` - UnbondingValidators []*sm.Validator `json:"unbonding_validators"` +type ResultListValidators struct { + BlockHeight int `json:"block_height"` + BondedValidators []*types.Validator `json:"bonded_validators"` + UnbondingValidators []*types.Validator `json:"unbonding_validators"` } -type ResponseDumpConsensusState struct { +type ResultDumpConsensusState struct { RoundState string `json:"round_state"` PeerRoundStates []string `json:"peer_round_states"` } -type ResponseListNames struct { +type ResultListNames struct { BlockHeight int `json:"block_height"` Names []*types.NameRegEntry `json:"names"` } -//---------------------------------------- -// event responses - -type ResponseEvent struct { - Event string `json:"event"` - Data interface{} `json:"data"` +type ResultGenPrivAccount struct { + PrivAccount *acm.PrivAccount `json:"priv_account"` } + +type ResultGetAccount struct { + Account *acm.Account `json:"account"` +} + +type ResultBroadcastTx struct { + Receipt Receipt `json:"receipt"` +} + +type Receipt struct { + TxHash []byte `json:"tx_hash"` + CreatesContract uint8 `json:"creates_contract"` + ContractAddr []byte `json:"contract_addr"` +} + +type ResultListUnconfirmedTxs struct { + Txs []types.Tx `json:"txs"` +} + +type ResultGetName struct { + Entry *types.NameRegEntry `json:"entry"` +} + +type ResultGenesis struct { + Genesis *stypes.GenesisDoc `json:"genesis"` +} + +type ResultSignTx struct { + Tx types.Tx `json:"tx"` +} + +type ResultEvent struct { + Event string `json:"event"` + Data types.EventData `json:"data"` +} + +//---------------------------------------- +// response & result types + +type Response struct { + JSONRPC string `json:"jsonrpc"` + Id string `json:"id"` + Result Result `json:"result"` + Error string `json:"error"` +} + +const ( + ResultTypeGetStorage = byte(0x01) + ResultTypeCall = byte(0x02) + ResultTypeListAccounts = byte(0x03) + ResultTypeDumpStorage = byte(0x04) + ResultTypeBlockchainInfo = byte(0x05) + ResultTypeGetBlock = byte(0x06) + ResultTypeStatus = byte(0x07) + ResultTypeNetInfo = byte(0x08) + ResultTypeListValidators = byte(0x09) + ResultTypeDumpConsensusState = byte(0x0A) + ResultTypeListNames = byte(0x0B) + ResultTypeGenPrivAccount = byte(0x0C) //*acm.PrivAccount + ResultTypeGetAccount = byte(0x0D) //*acm.Account + ResultTypeBroadcastTx = byte(0x0E) //*types.Receipt + ResultTypeListUnconfirmedTxs = byte(0x0F) //[]types.Tx + ResultTypeGetName = byte(0x10) // *types.NameRegEntry + ResultTypeGenesis = byte(0x11) // *stypes.GenesisDoc + ResultTypeSignTx = byte(0x12) // Tx >>>> double interface! + ResultTypeEvent = byte(0x13) // so websockets can respond to rpc functions +) + +type Result interface{} + +// for wire.readReflect +var _ = wire.RegisterInterface( + struct{ Result }{}, + wire.ConcreteType{&ResultGetStorage{}, ResultTypeGetStorage}, + wire.ConcreteType{&ResultCall{}, ResultTypeCall}, + wire.ConcreteType{&ResultListAccounts{}, ResultTypeListAccounts}, + wire.ConcreteType{&ResultDumpStorage{}, ResultTypeDumpStorage}, + wire.ConcreteType{&ResultBlockchainInfo{}, ResultTypeBlockchainInfo}, + wire.ConcreteType{&ResultGetBlock{}, ResultTypeGetBlock}, + wire.ConcreteType{&ResultStatus{}, ResultTypeStatus}, + wire.ConcreteType{&ResultNetInfo{}, ResultTypeNetInfo}, + wire.ConcreteType{&ResultListValidators{}, ResultTypeListValidators}, + wire.ConcreteType{&ResultDumpConsensusState{}, ResultTypeDumpConsensusState}, + wire.ConcreteType{&ResultListNames{}, ResultTypeListNames}, + wire.ConcreteType{&ResultGenPrivAccount{}, ResultTypeGenPrivAccount}, + wire.ConcreteType{&ResultGetAccount{}, ResultTypeGetAccount}, + wire.ConcreteType{&ResultBroadcastTx{}, ResultTypeBroadcastTx}, + wire.ConcreteType{&ResultListUnconfirmedTxs{}, ResultTypeListUnconfirmedTxs}, + wire.ConcreteType{&ResultGetName{}, ResultTypeGetName}, + wire.ConcreteType{&ResultGenesis{}, ResultTypeGenesis}, + wire.ConcreteType{&ResultSignTx{}, ResultTypeSignTx}, + wire.ConcreteType{&ResultEvent{}, ResultTypeEvent}, +) diff --git a/rpc/core_client/client_methods.go b/rpc/core_client/client_methods.go index 42556848..a2314526 100644 --- a/rpc/core_client/client_methods.go +++ b/rpc/core_client/client_methods.go @@ -5,38 +5,37 @@ package core_client import ( "fmt" acm "github.com/tendermint/tendermint/account" - "github.com/tendermint/tendermint/wire" ctypes "github.com/tendermint/tendermint/rpc/core/types" rpctypes "github.com/tendermint/tendermint/rpc/types" - sm "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/wire" "io/ioutil" "net/http" ) type Client interface { - BlockchainInfo(minHeight int, maxHeight int) (*ctypes.ResponseBlockchainInfo, error) - BroadcastTx(tx types.Tx) (*ctypes.Receipt, error) - Call(fromAddress []byte, toAddress []byte, data []byte) (*ctypes.ResponseCall, error) - CallCode(fromAddress []byte, code []byte, data []byte) (*ctypes.ResponseCall, error) - DumpConsensusState() (*ctypes.ResponseDumpConsensusState, error) - DumpStorage(address []byte) (*ctypes.ResponseDumpStorage, error) - GenPrivAccount() (*acm.PrivAccount, error) - Genesis() (*sm.GenesisDoc, error) - GetAccount(address []byte) (*acm.Account, error) - GetBlock(height int) (*ctypes.ResponseGetBlock, error) - GetName(name string) (*types.NameRegEntry, error) - GetStorage(address []byte, key []byte) (*ctypes.ResponseGetStorage, error) - ListAccounts() (*ctypes.ResponseListAccounts, error) - ListNames() (*ctypes.ResponseListNames, error) - ListUnconfirmedTxs() ([]types.Tx, error) - ListValidators() (*ctypes.ResponseListValidators, error) - NetInfo() (*ctypes.ResponseNetInfo, error) - SignTx(tx types.Tx, privAccounts []*acm.PrivAccount) (types.Tx, error) - Status() (*ctypes.ResponseStatus, error) + BlockchainInfo(minHeight int, maxHeight int) (*ctypes.ResultBlockchainInfo, error) + BroadcastTx(tx types.Tx) (*ctypes.ResultBroadcastTx, error) + Call(fromAddress []byte, toAddress []byte, data []byte) (*ctypes.ResultCall, error) + CallCode(fromAddress []byte, code []byte, data []byte) (*ctypes.ResultCall, error) + DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) + DumpStorage(address []byte) (*ctypes.ResultDumpStorage, error) + GenPrivAccount() (*ctypes.ResultGenPrivAccount, error) + Genesis() (*ctypes.ResultGenesis, error) + GetAccount(address []byte) (*ctypes.ResultGetAccount, error) + GetBlock(height int) (*ctypes.ResultGetBlock, error) + GetName(name string) (*ctypes.ResultGetName, error) + GetStorage(address []byte, key []byte) (*ctypes.ResultGetStorage, error) + ListAccounts() (*ctypes.ResultListAccounts, error) + ListNames() (*ctypes.ResultListNames, error) + ListUnconfirmedTxs() (*ctypes.ResultListUnconfirmedTxs, error) + ListValidators() (*ctypes.ResultListValidators, error) + NetInfo() (*ctypes.ResultNetInfo, error) + SignTx(tx types.Tx, privAccounts []*acm.PrivAccount) (*ctypes.ResultSignTx, error) + Status() (*ctypes.ResultStatus, error) } -func (c *ClientHTTP) BlockchainInfo(minHeight int, maxHeight int) (*ctypes.ResponseBlockchainInfo, error) { +func (c *ClientHTTP) BlockchainInfo(minHeight int, maxHeight int) (*ctypes.ResultBlockchainInfo, error) { values, err := argsToURLValues([]string{"minHeight", "maxHeight"}, minHeight, maxHeight) if err != nil { return nil, err @@ -51,10 +50,10 @@ func (c *ClientHTTP) BlockchainInfo(minHeight int, maxHeight int) (*ctypes.Respo return nil, err } var response struct { - Result *ctypes.ResponseBlockchainInfo `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` + Result *ctypes.ResultBlockchainInfo `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` } wire.ReadJSON(&response, body, &err) if err != nil { @@ -66,7 +65,7 @@ func (c *ClientHTTP) BlockchainInfo(minHeight int, maxHeight int) (*ctypes.Respo return response.Result, nil } -func (c *ClientHTTP) BroadcastTx(tx types.Tx) (*ctypes.Receipt, error) { +func (c *ClientHTTP) BroadcastTx(tx types.Tx) (*ctypes.ResultBroadcastTx, error) { values, err := argsToURLValues([]string{"tx"}, tx) if err != nil { return nil, err @@ -81,10 +80,10 @@ func (c *ClientHTTP) BroadcastTx(tx types.Tx) (*ctypes.Receipt, error) { return nil, err } var response struct { - Result *ctypes.Receipt `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` + Result *ctypes.ResultBroadcastTx `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` } wire.ReadJSON(&response, body, &err) if err != nil { @@ -96,7 +95,7 @@ func (c *ClientHTTP) BroadcastTx(tx types.Tx) (*ctypes.Receipt, error) { return response.Result, nil } -func (c *ClientHTTP) Call(fromAddress []byte, toAddress []byte, data []byte) (*ctypes.ResponseCall, error) { +func (c *ClientHTTP) Call(fromAddress []byte, toAddress []byte, data []byte) (*ctypes.ResultCall, error) { values, err := argsToURLValues([]string{"fromAddress", "toAddress", "data"}, fromAddress, toAddress, data) if err != nil { return nil, err @@ -111,10 +110,10 @@ func (c *ClientHTTP) Call(fromAddress []byte, toAddress []byte, data []byte) (*c return nil, err } var response struct { - Result *ctypes.ResponseCall `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` + Result *ctypes.ResultCall `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` } wire.ReadJSON(&response, body, &err) if err != nil { @@ -126,7 +125,7 @@ func (c *ClientHTTP) Call(fromAddress []byte, toAddress []byte, data []byte) (*c return response.Result, nil } -func (c *ClientHTTP) CallCode(fromAddress []byte, code []byte, data []byte) (*ctypes.ResponseCall, error) { +func (c *ClientHTTP) CallCode(fromAddress []byte, code []byte, data []byte) (*ctypes.ResultCall, error) { values, err := argsToURLValues([]string{"fromAddress", "code", "data"}, fromAddress, code, data) if err != nil { return nil, err @@ -141,10 +140,10 @@ func (c *ClientHTTP) CallCode(fromAddress []byte, code []byte, data []byte) (*ct return nil, err } var response struct { - Result *ctypes.ResponseCall `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` + Result *ctypes.ResultCall `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` } wire.ReadJSON(&response, body, &err) if err != nil { @@ -156,7 +155,7 @@ func (c *ClientHTTP) CallCode(fromAddress []byte, code []byte, data []byte) (*ct return response.Result, nil } -func (c *ClientHTTP) DumpConsensusState() (*ctypes.ResponseDumpConsensusState, error) { +func (c *ClientHTTP) DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) { values, err := argsToURLValues(nil) if err != nil { return nil, err @@ -171,10 +170,10 @@ func (c *ClientHTTP) DumpConsensusState() (*ctypes.ResponseDumpConsensusState, e return nil, err } var response struct { - Result *ctypes.ResponseDumpConsensusState `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` + Result *ctypes.ResultDumpConsensusState `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` } wire.ReadJSON(&response, body, &err) if err != nil { @@ -186,7 +185,7 @@ func (c *ClientHTTP) DumpConsensusState() (*ctypes.ResponseDumpConsensusState, e return response.Result, nil } -func (c *ClientHTTP) DumpStorage(address []byte) (*ctypes.ResponseDumpStorage, error) { +func (c *ClientHTTP) DumpStorage(address []byte) (*ctypes.ResultDumpStorage, error) { values, err := argsToURLValues([]string{"address"}, address) if err != nil { return nil, err @@ -201,10 +200,10 @@ func (c *ClientHTTP) DumpStorage(address []byte) (*ctypes.ResponseDumpStorage, e return nil, err } var response struct { - Result *ctypes.ResponseDumpStorage `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` + Result *ctypes.ResultDumpStorage `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` } wire.ReadJSON(&response, body, &err) if err != nil { @@ -216,7 +215,7 @@ func (c *ClientHTTP) DumpStorage(address []byte) (*ctypes.ResponseDumpStorage, e return response.Result, nil } -func (c *ClientHTTP) GenPrivAccount() (*acm.PrivAccount, error) { +func (c *ClientHTTP) GenPrivAccount() (*ctypes.ResultGenPrivAccount, error) { values, err := argsToURLValues(nil) if err != nil { return nil, err @@ -231,10 +230,10 @@ func (c *ClientHTTP) GenPrivAccount() (*acm.PrivAccount, error) { return nil, err } var response struct { - Result *acm.PrivAccount `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` + Result *ctypes.ResultGenPrivAccount `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` } wire.ReadJSON(&response, body, &err) if err != nil { @@ -246,7 +245,7 @@ func (c *ClientHTTP) GenPrivAccount() (*acm.PrivAccount, error) { return response.Result, nil } -func (c *ClientHTTP) Genesis() (*sm.GenesisDoc, error) { +func (c *ClientHTTP) Genesis() (*ctypes.ResultGenesis, error) { values, err := argsToURLValues(nil) if err != nil { return nil, err @@ -261,10 +260,10 @@ func (c *ClientHTTP) Genesis() (*sm.GenesisDoc, error) { return nil, err } var response struct { - Result *sm.GenesisDoc `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` + Result *ctypes.ResultGenesis `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` } wire.ReadJSON(&response, body, &err) if err != nil { @@ -276,7 +275,7 @@ func (c *ClientHTTP) Genesis() (*sm.GenesisDoc, error) { return response.Result, nil } -func (c *ClientHTTP) GetAccount(address []byte) (*acm.Account, error) { +func (c *ClientHTTP) GetAccount(address []byte) (*ctypes.ResultGetAccount, error) { values, err := argsToURLValues([]string{"address"}, address) if err != nil { return nil, err @@ -291,10 +290,10 @@ func (c *ClientHTTP) GetAccount(address []byte) (*acm.Account, error) { return nil, err } var response struct { - Result *acm.Account `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` + Result *ctypes.ResultGetAccount `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` } wire.ReadJSON(&response, body, &err) if err != nil { @@ -306,7 +305,7 @@ func (c *ClientHTTP) GetAccount(address []byte) (*acm.Account, error) { return response.Result, nil } -func (c *ClientHTTP) GetBlock(height int) (*ctypes.ResponseGetBlock, error) { +func (c *ClientHTTP) GetBlock(height int) (*ctypes.ResultGetBlock, error) { values, err := argsToURLValues([]string{"height"}, height) if err != nil { return nil, err @@ -321,10 +320,10 @@ func (c *ClientHTTP) GetBlock(height int) (*ctypes.ResponseGetBlock, error) { return nil, err } var response struct { - Result *ctypes.ResponseGetBlock `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` + Result *ctypes.ResultGetBlock `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` } wire.ReadJSON(&response, body, &err) if err != nil { @@ -336,7 +335,7 @@ func (c *ClientHTTP) GetBlock(height int) (*ctypes.ResponseGetBlock, error) { return response.Result, nil } -func (c *ClientHTTP) GetName(name string) (*types.NameRegEntry, error) { +func (c *ClientHTTP) GetName(name string) (*ctypes.ResultGetName, error) { values, err := argsToURLValues([]string{"name"}, name) if err != nil { return nil, err @@ -351,10 +350,10 @@ func (c *ClientHTTP) GetName(name string) (*types.NameRegEntry, error) { return nil, err } var response struct { - Result *types.NameRegEntry `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` + Result *ctypes.ResultGetName `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` } wire.ReadJSON(&response, body, &err) if err != nil { @@ -366,7 +365,7 @@ func (c *ClientHTTP) GetName(name string) (*types.NameRegEntry, error) { return response.Result, nil } -func (c *ClientHTTP) GetStorage(address []byte, key []byte) (*ctypes.ResponseGetStorage, error) { +func (c *ClientHTTP) GetStorage(address []byte, key []byte) (*ctypes.ResultGetStorage, error) { values, err := argsToURLValues([]string{"address", "key"}, address, key) if err != nil { return nil, err @@ -381,487 +380,7 @@ func (c *ClientHTTP) GetStorage(address []byte, key []byte) (*ctypes.ResponseGet return nil, err } var response struct { - Result *ctypes.ResponseGetStorage `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientHTTP) ListAccounts() (*ctypes.ResponseListAccounts, error) { - values, err := argsToURLValues(nil) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["ListAccounts"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - var response struct { - Result *ctypes.ResponseListAccounts `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientHTTP) ListNames() (*ctypes.ResponseListNames, error) { - values, err := argsToURLValues(nil) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["ListNames"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - var response struct { - Result *ctypes.ResponseListNames `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientHTTP) ListUnconfirmedTxs() ([]types.Tx, error) { - values, err := argsToURLValues(nil) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["ListUnconfirmedTxs"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - var response struct { - Result []types.Tx `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientHTTP) ListValidators() (*ctypes.ResponseListValidators, error) { - values, err := argsToURLValues(nil) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["ListValidators"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - var response struct { - Result *ctypes.ResponseListValidators `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientHTTP) NetInfo() (*ctypes.ResponseNetInfo, error) { - values, err := argsToURLValues(nil) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["NetInfo"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - var response struct { - Result *ctypes.ResponseNetInfo `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientHTTP) SignTx(tx types.Tx, privAccounts []*acm.PrivAccount) (types.Tx, error) { - values, err := argsToURLValues([]string{"tx", "privAccounts"}, tx, privAccounts) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["SignTx"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - var response struct { - Result types.Tx `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientHTTP) Status() (*ctypes.ResponseStatus, error) { - values, err := argsToURLValues(nil) - if err != nil { - return nil, err - } - resp, err := http.PostForm(c.addr+reverseFuncMap["Status"], values) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - var response struct { - Result *ctypes.ResponseStatus `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientJSON) BlockchainInfo(minHeight int, maxHeight int) (*ctypes.ResponseBlockchainInfo, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["BlockchainInfo"], - Params: []interface{}{minHeight, maxHeight}, - Id: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - var response struct { - Result *ctypes.ResponseBlockchainInfo `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientJSON) BroadcastTx(tx types.Tx) (*ctypes.Receipt, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["BroadcastTx"], - Params: []interface{}{tx}, - Id: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - var response struct { - Result *ctypes.Receipt `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientJSON) Call(fromAddress []byte, toAddress []byte, data []byte) (*ctypes.ResponseCall, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["Call"], - Params: []interface{}{fromAddress, toAddress, data}, - Id: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - var response struct { - Result *ctypes.ResponseCall `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientJSON) CallCode(fromAddress []byte, code []byte, data []byte) (*ctypes.ResponseCall, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["CallCode"], - Params: []interface{}{fromAddress, code, data}, - Id: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - var response struct { - Result *ctypes.ResponseCall `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientJSON) DumpConsensusState() (*ctypes.ResponseDumpConsensusState, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["DumpConsensusState"], - Params: []interface{}{}, - Id: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - var response struct { - Result *ctypes.ResponseDumpConsensusState `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientJSON) DumpStorage(address []byte) (*ctypes.ResponseDumpStorage, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["DumpStorage"], - Params: []interface{}{address}, - Id: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - var response struct { - Result *ctypes.ResponseDumpStorage `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientJSON) GenPrivAccount() (*acm.PrivAccount, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["GenPrivAccount"], - Params: []interface{}{}, - Id: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - var response struct { - Result *acm.PrivAccount `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientJSON) Genesis() (*sm.GenesisDoc, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["Genesis"], - Params: []interface{}{}, - Id: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - var response struct { - Result *sm.GenesisDoc `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientJSON) GetAccount(address []byte) (*acm.Account, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["GetAccount"], - Params: []interface{}{address}, - Id: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - var response struct { - Result *acm.Account `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientJSON) GetBlock(height int) (*ctypes.ResponseGetBlock, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["GetBlock"], - Params: []interface{}{height}, - Id: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - var response struct { - Result *ctypes.ResponseGetBlock `json:"result"` + Result *ctypes.ResultGetStorage `json:"result"` Error string `json:"error"` Id string `json:"id"` JSONRPC string `json:"jsonrpc"` @@ -876,46 +395,22 @@ func (c *ClientJSON) GetBlock(height int) (*ctypes.ResponseGetBlock, error) { return response.Result, nil } -func (c *ClientJSON) GetName(name string) (*types.NameRegEntry, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["GetName"], - Params: []interface{}{name}, - Id: "", +func (c *ClientHTTP) ListAccounts() (*ctypes.ResultListAccounts, error) { + values, err := argsToURLValues(nil) + if err != nil { + return nil, err } - body, err := c.RequestResponse(request) + resp, err := http.PostForm(c.addr+reverseFuncMap["ListAccounts"], values) + if err != nil { + return nil, err + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, err } var response struct { - Result *types.NameRegEntry `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientJSON) GetStorage(address []byte, key []byte) (*ctypes.ResponseGetStorage, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["GetStorage"], - Params: []interface{}{address, key}, - Id: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - var response struct { - Result *ctypes.ResponseGetStorage `json:"result"` + Result *ctypes.ResultListAccounts `json:"result"` Error string `json:"error"` Id string `json:"id"` JSONRPC string `json:"jsonrpc"` @@ -930,127 +425,22 @@ func (c *ClientJSON) GetStorage(address []byte, key []byte) (*ctypes.ResponseGet return response.Result, nil } -func (c *ClientJSON) ListAccounts() (*ctypes.ResponseListAccounts, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["ListAccounts"], - Params: []interface{}{}, - Id: "", +func (c *ClientHTTP) ListNames() (*ctypes.ResultListNames, error) { + values, err := argsToURLValues(nil) + if err != nil { + return nil, err } - body, err := c.RequestResponse(request) + resp, err := http.PostForm(c.addr+reverseFuncMap["ListNames"], values) + if err != nil { + return nil, err + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, err } var response struct { - Result *ctypes.ResponseListAccounts `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientJSON) ListNames() (*ctypes.ResponseListNames, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["ListNames"], - Params: []interface{}{}, - Id: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - var response struct { - Result *ctypes.ResponseListNames `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientJSON) ListUnconfirmedTxs() ([]types.Tx, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["ListUnconfirmedTxs"], - Params: []interface{}{}, - Id: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - var response struct { - Result []types.Tx `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientJSON) ListValidators() (*ctypes.ResponseListValidators, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["ListValidators"], - Params: []interface{}{}, - Id: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - var response struct { - Result *ctypes.ResponseListValidators `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` - } - wire.ReadJSON(&response, body, &err) - if err != nil { - return nil, err - } - if response.Error != "" { - return nil, fmt.Errorf(response.Error) - } - return response.Result, nil -} - -func (c *ClientJSON) NetInfo() (*ctypes.ResponseNetInfo, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["NetInfo"], - Params: []interface{}{}, - Id: "", - } - body, err := c.RequestResponse(request) - if err != nil { - return nil, err - } - var response struct { - Result *ctypes.ResponseNetInfo `json:"result"` + Result *ctypes.ResultListNames `json:"result"` Error string `json:"error"` Id string `json:"id"` JSONRPC string `json:"jsonrpc"` @@ -1065,22 +455,25 @@ func (c *ClientJSON) NetInfo() (*ctypes.ResponseNetInfo, error) { return response.Result, nil } -func (c *ClientJSON) SignTx(tx types.Tx, privAccounts []*acm.PrivAccount) (types.Tx, error) { - request := rpctypes.RPCRequest{ - JSONRPC: "2.0", - Method: reverseFuncMap["SignTx"], - Params: []interface{}{tx, privAccounts}, - Id: "", +func (c *ClientHTTP) ListUnconfirmedTxs() (*ctypes.ResultListUnconfirmedTxs, error) { + values, err := argsToURLValues(nil) + if err != nil { + return nil, err } - body, err := c.RequestResponse(request) + resp, err := http.PostForm(c.addr+reverseFuncMap["ListUnconfirmedTxs"], values) + if err != nil { + return nil, err + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, err } var response struct { - Result types.Tx `json:"result"` - Error string `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` + Result *ctypes.ResultListUnconfirmedTxs `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` } wire.ReadJSON(&response, body, &err) if err != nil { @@ -1092,10 +485,238 @@ func (c *ClientJSON) SignTx(tx types.Tx, privAccounts []*acm.PrivAccount) (types return response.Result, nil } -func (c *ClientJSON) Status() (*ctypes.ResponseStatus, error) { +func (c *ClientHTTP) ListValidators() (*ctypes.ResultListValidators, error) { + values, err := argsToURLValues(nil) + if err != nil { + return nil, err + } + resp, err := http.PostForm(c.addr+reverseFuncMap["ListValidators"], values) + if err != nil { + return nil, err + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultListValidators `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + +func (c *ClientHTTP) NetInfo() (*ctypes.ResultNetInfo, error) { + values, err := argsToURLValues(nil) + if err != nil { + return nil, err + } + resp, err := http.PostForm(c.addr+reverseFuncMap["NetInfo"], values) + if err != nil { + return nil, err + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultNetInfo `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + +func (c *ClientHTTP) SignTx(tx types.Tx, privAccounts []*acm.PrivAccount) (*ctypes.ResultSignTx, error) { + values, err := argsToURLValues([]string{"tx", "privAccounts"}, tx, privAccounts) + if err != nil { + return nil, err + } + resp, err := http.PostForm(c.addr+reverseFuncMap["SignTx"], values) + if err != nil { + return nil, err + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultSignTx `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + +func (c *ClientHTTP) Status() (*ctypes.ResultStatus, error) { + values, err := argsToURLValues(nil) + if err != nil { + return nil, err + } + resp, err := http.PostForm(c.addr+reverseFuncMap["Status"], values) + if err != nil { + return nil, err + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultStatus `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + +func (c *ClientJSON) BlockchainInfo(minHeight int, maxHeight int) (*ctypes.ResultBlockchainInfo, error) { request := rpctypes.RPCRequest{ JSONRPC: "2.0", - Method: reverseFuncMap["Status"], + Method: reverseFuncMap["BlockchainInfo"], + Params: []interface{}{minHeight, maxHeight}, + Id: "", + } + body, err := c.RequestResponse(request) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultBlockchainInfo `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + +func (c *ClientJSON) BroadcastTx(tx types.Tx) (*ctypes.ResultBroadcastTx, error) { + request := rpctypes.RPCRequest{ + JSONRPC: "2.0", + Method: reverseFuncMap["BroadcastTx"], + Params: []interface{}{tx}, + Id: "", + } + body, err := c.RequestResponse(request) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultBroadcastTx `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + +func (c *ClientJSON) Call(fromAddress []byte, toAddress []byte, data []byte) (*ctypes.ResultCall, error) { + request := rpctypes.RPCRequest{ + JSONRPC: "2.0", + Method: reverseFuncMap["Call"], + Params: []interface{}{fromAddress, toAddress, data}, + Id: "", + } + body, err := c.RequestResponse(request) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultCall `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + +func (c *ClientJSON) CallCode(fromAddress []byte, code []byte, data []byte) (*ctypes.ResultCall, error) { + request := rpctypes.RPCRequest{ + JSONRPC: "2.0", + Method: reverseFuncMap["CallCode"], + Params: []interface{}{fromAddress, code, data}, + Id: "", + } + body, err := c.RequestResponse(request) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultCall `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + +func (c *ClientJSON) DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) { + request := rpctypes.RPCRequest{ + JSONRPC: "2.0", + Method: reverseFuncMap["DumpConsensusState"], Params: []interface{}{}, Id: "", } @@ -1104,7 +725,142 @@ func (c *ClientJSON) Status() (*ctypes.ResponseStatus, error) { return nil, err } var response struct { - Result *ctypes.ResponseStatus `json:"result"` + Result *ctypes.ResultDumpConsensusState `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + +func (c *ClientJSON) DumpStorage(address []byte) (*ctypes.ResultDumpStorage, error) { + request := rpctypes.RPCRequest{ + JSONRPC: "2.0", + Method: reverseFuncMap["DumpStorage"], + Params: []interface{}{address}, + Id: "", + } + body, err := c.RequestResponse(request) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultDumpStorage `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + +func (c *ClientJSON) GenPrivAccount() (*ctypes.ResultGenPrivAccount, error) { + request := rpctypes.RPCRequest{ + JSONRPC: "2.0", + Method: reverseFuncMap["GenPrivAccount"], + Params: []interface{}{}, + Id: "", + } + body, err := c.RequestResponse(request) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultGenPrivAccount `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + +func (c *ClientJSON) Genesis() (*ctypes.ResultGenesis, error) { + request := rpctypes.RPCRequest{ + JSONRPC: "2.0", + Method: reverseFuncMap["Genesis"], + Params: []interface{}{}, + Id: "", + } + body, err := c.RequestResponse(request) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultGenesis `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + +func (c *ClientJSON) GetAccount(address []byte) (*ctypes.ResultGetAccount, error) { + request := rpctypes.RPCRequest{ + JSONRPC: "2.0", + Method: reverseFuncMap["GetAccount"], + Params: []interface{}{address}, + Id: "", + } + body, err := c.RequestResponse(request) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultGetAccount `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + +func (c *ClientJSON) GetBlock(height int) (*ctypes.ResultGetBlock, error) { + request := rpctypes.RPCRequest{ + JSONRPC: "2.0", + Method: reverseFuncMap["GetBlock"], + Params: []interface{}{height}, + Id: "", + } + body, err := c.RequestResponse(request) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultGetBlock `json:"result"` Error string `json:"error"` Id string `json:"id"` JSONRPC string `json:"jsonrpc"` @@ -1118,3 +874,246 @@ func (c *ClientJSON) Status() (*ctypes.ResponseStatus, error) { } return response.Result, nil } + +func (c *ClientJSON) GetName(name string) (*ctypes.ResultGetName, error) { + request := rpctypes.RPCRequest{ + JSONRPC: "2.0", + Method: reverseFuncMap["GetName"], + Params: []interface{}{name}, + Id: "", + } + body, err := c.RequestResponse(request) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultGetName `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + +func (c *ClientJSON) GetStorage(address []byte, key []byte) (*ctypes.ResultGetStorage, error) { + request := rpctypes.RPCRequest{ + JSONRPC: "2.0", + Method: reverseFuncMap["GetStorage"], + Params: []interface{}{address, key}, + Id: "", + } + body, err := c.RequestResponse(request) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultGetStorage `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + +func (c *ClientJSON) ListAccounts() (*ctypes.ResultListAccounts, error) { + request := rpctypes.RPCRequest{ + JSONRPC: "2.0", + Method: reverseFuncMap["ListAccounts"], + Params: []interface{}{}, + Id: "", + } + body, err := c.RequestResponse(request) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultListAccounts `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + +func (c *ClientJSON) ListNames() (*ctypes.ResultListNames, error) { + request := rpctypes.RPCRequest{ + JSONRPC: "2.0", + Method: reverseFuncMap["ListNames"], + Params: []interface{}{}, + Id: "", + } + body, err := c.RequestResponse(request) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultListNames `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + +func (c *ClientJSON) ListUnconfirmedTxs() (*ctypes.ResultListUnconfirmedTxs, error) { + request := rpctypes.RPCRequest{ + JSONRPC: "2.0", + Method: reverseFuncMap["ListUnconfirmedTxs"], + Params: []interface{}{}, + Id: "", + } + body, err := c.RequestResponse(request) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultListUnconfirmedTxs `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + +func (c *ClientJSON) ListValidators() (*ctypes.ResultListValidators, error) { + request := rpctypes.RPCRequest{ + JSONRPC: "2.0", + Method: reverseFuncMap["ListValidators"], + Params: []interface{}{}, + Id: "", + } + body, err := c.RequestResponse(request) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultListValidators `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + +func (c *ClientJSON) NetInfo() (*ctypes.ResultNetInfo, error) { + request := rpctypes.RPCRequest{ + JSONRPC: "2.0", + Method: reverseFuncMap["NetInfo"], + Params: []interface{}{}, + Id: "", + } + body, err := c.RequestResponse(request) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultNetInfo `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + +func (c *ClientJSON) SignTx(tx types.Tx, privAccounts []*acm.PrivAccount) (*ctypes.ResultSignTx, error) { + request := rpctypes.RPCRequest{ + JSONRPC: "2.0", + Method: reverseFuncMap["SignTx"], + Params: []interface{}{tx, privAccounts}, + Id: "", + } + body, err := c.RequestResponse(request) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultSignTx `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} + +func (c *ClientJSON) Status() (*ctypes.ResultStatus, error) { + request := rpctypes.RPCRequest{ + JSONRPC: "2.0", + Method: reverseFuncMap["Status"], + Params: []interface{}{}, + Id: "", + } + body, err := c.RequestResponse(request) + if err != nil { + return nil, err + } + var response struct { + Result *ctypes.ResultStatus `json:"result"` + Error string `json:"error"` + Id string `json:"id"` + JSONRPC string `json:"jsonrpc"` + } + wire.ReadJSON(&response, body, &err) + if err != nil { + return nil, err + } + if response.Error != "" { + return nil, fmt.Errorf(response.Error) + } + return response.Result, nil +} diff --git a/rpc/core_client/log.go b/rpc/core_client/log.go new file mode 100644 index 00000000..a3784715 --- /dev/null +++ b/rpc/core_client/log.go @@ -0,0 +1,7 @@ +package core_client + +import ( + "github.com/tendermint/tendermint/Godeps/_workspace/src/github.com/tendermint/log15" +) + +var log = log15.New("module", "core_client") diff --git a/rpc/client/ws_client.go b/rpc/core_client/ws_client.go similarity index 77% rename from rpc/client/ws_client.go rename to rpc/core_client/ws_client.go index 85f35df2..f33ece79 100644 --- a/rpc/client/ws_client.go +++ b/rpc/core_client/ws_client.go @@ -1,4 +1,4 @@ -package rpcclient +package core_client import ( "encoding/json" @@ -8,27 +8,28 @@ import ( "github.com/tendermint/tendermint/Godeps/_workspace/src/github.com/gorilla/websocket" . "github.com/tendermint/tendermint/common" _ "github.com/tendermint/tendermint/config/tendermint_test" + ctypes "github.com/tendermint/tendermint/rpc/core/types" "github.com/tendermint/tendermint/rpc/types" ) const wsEventsChannelCapacity = 10 -const wsResponsesChannelCapacity = 10 +const wsResultsChannelCapacity = 10 type WSClient struct { QuitService Address string *websocket.Conn - EventsCh chan rpctypes.RPCEventResult - ResponsesCh chan rpctypes.RPCResponse + EventsCh chan ctypes.ResultEvent + ResultsCh chan ctypes.Result } // create a new connection func NewWSClient(addr string) *WSClient { wsClient := &WSClient{ - Address: addr, - Conn: nil, - EventsCh: make(chan rpctypes.RPCEventResult, wsEventsChannelCapacity), - ResponsesCh: make(chan rpctypes.RPCResponse, wsResponsesChannelCapacity), + Address: addr, + Conn: nil, + EventsCh: make(chan ctypes.ResultEvent, wsEventsChannelCapacity), + ResultsCh: make(chan ctypes.Result, wsResultsChannelCapacity), } wsClient.QuitService = *NewQuitService(log, "WSClient", wsClient) return wsClient @@ -68,19 +69,16 @@ func (wsc *WSClient) receiveEventsRoutine() { wsc.Stop() break } else { - var response rpctypes.RPCResponse + var response ctypes.Response if err := json.Unmarshal(data, &response); err != nil { log.Info(Fmt("WSClient failed to parse message: %v", err)) wsc.Stop() break } if strings.HasSuffix(response.Id, "#event") { - result := response.Result.(map[string]interface{}) - event := result["event"].(string) - data := result["data"] - wsc.EventsCh <- rpctypes.RPCEventResult{event, data} + wsc.EventsCh <- response.Result.(ctypes.ResultEvent) } else { - wsc.ResponsesCh <- response + wsc.ResultsCh <- response.Result } } } diff --git a/rpc/server/handlers.go b/rpc/server/handlers.go index 16942fac..4ba885e1 100644 --- a/rpc/server/handlers.go +++ b/rpc/server/handlers.go @@ -14,6 +14,7 @@ import ( "github.com/tendermint/tendermint/Godeps/_workspace/src/github.com/gorilla/websocket" . "github.com/tendermint/tendermint/common" "github.com/tendermint/tendermint/events" + ctypes "github.com/tendermint/tendermint/rpc/core/types" . "github.com/tendermint/tendermint/rpc/types" "github.com/tendermint/tendermint/wire" ) @@ -338,7 +339,7 @@ func (wsc *WSConnection) readRoutine() { log.Notice("Subscribe to event", "id", wsc.id, "event", event) wsc.evsw.AddListenerForEvent(wsc.id, event, func(msg interface{}) { // NOTE: RPCResponses of subscribed events have id suffix "#event" - wsc.writeRPCResponse(NewRPCResponse(request.Id+"#event", RPCEventResult{event, msg}, "")) + wsc.writeRPCResponse(NewRPCResponse(request.Id+"#event", ctypes.ResultEvent{event, msg}, "")) }) continue } diff --git a/rpc/server/http_server.go b/rpc/server/http_server.go index 6d03668f..16f6a965 100644 --- a/rpc/server/http_server.go +++ b/rpc/server/http_server.go @@ -11,9 +11,9 @@ import ( "time" "github.com/tendermint/tendermint/alert" - "github.com/tendermint/tendermint/wire" . "github.com/tendermint/tendermint/common" . "github.com/tendermint/tendermint/rpc/types" + "github.com/tendermint/tendermint/wire" ) func StartHTTPServer(listenAddr string, handler http.Handler) (net.Listener, error) { @@ -33,10 +33,10 @@ func StartHTTPServer(listenAddr string, handler http.Handler) (net.Listener, err } func WriteRPCResponse(w http.ResponseWriter, res RPCResponse) { - buf, n, err := new(bytes.Buffer), new(int64), new(error) - wire.WriteJSON(res, buf, n, err) - if *err != nil { - log.Warn("Failed to write RPC response", "error", err) + buf, n, err := new(bytes.Buffer), int64(0), error(nil) + wire.WriteJSON(res, buf, &n, &err) + if err != nil { + log.Error("Failed to write RPC response", "error", err, "res", res) } w.Header().Set("Content-Type", "application/json") diff --git a/rpc/test/client_ws_test.go b/rpc/test/client_ws_test.go index 70b21c96..99176484 100644 --- a/rpc/test/client_ws_test.go +++ b/rpc/test/client_ws_test.go @@ -120,7 +120,7 @@ func TestWSCallWait(t *testing.T) { tx := makeDefaultCallTx(t, wsTyp, nil, code, amt, gasLim, fee) receipt := broadcastTx(t, wsTyp, tx) contractAddr = receipt.ContractAddr - }, unmarshalValidateCall(amt, returnCode)) + }, unmarshalValidateTx(amt, returnCode)) // susbscribe to the new contract amt = int64(10001) @@ -135,7 +135,7 @@ func TestWSCallWait(t *testing.T) { tx := makeDefaultCallTx(t, wsTyp, contractAddr, data, amt, gasLim, fee) receipt := broadcastTx(t, wsTyp, tx) contractAddr = receipt.ContractAddr - }, unmarshalValidateCall(amt, returnVal)) + }, unmarshalValidateTx(amt, returnVal)) } // create a contract and send it a msg without waiting. wait for contract event @@ -165,7 +165,7 @@ func TestWSCallNoWait(t *testing.T) { waitForEvent(t, con, eid, true, func() { tx := makeDefaultCallTx(t, wsTyp, contractAddr, data, amt, gasLim, fee) broadcastTx(t, wsTyp, tx) - }, unmarshalValidateCall(amt, returnVal)) + }, unmarshalValidateTx(amt, returnVal)) } // create two contracts, one of which calls the other @@ -208,5 +208,5 @@ func TestWSCallCall(t *testing.T) { tx := makeDefaultCallTx(t, wsTyp, contractAddr2, nil, amt, gasLim, fee) broadcastTx(t, wsTyp, tx) *txid = types.TxID(chainID, tx) - }, unmarshalValidateCallCall(user[0].Address, returnVal, txid)) + }, unmarshalValidateCall(user[0].Address, returnVal, txid)) } diff --git a/rpc/test/helpers.go b/rpc/test/helpers.go index 8a553ead..1e798b56 100644 --- a/rpc/test/helpers.go +++ b/rpc/test/helpers.go @@ -11,7 +11,6 @@ import ( "github.com/tendermint/tendermint/p2p" ctypes "github.com/tendermint/tendermint/rpc/core/types" cclient "github.com/tendermint/tendermint/rpc/core_client" - "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/types" ) @@ -51,7 +50,7 @@ func makeUsers(n int) []*acm.PrivAccount { func newNode(ready chan struct{}) { // Create & start node node = nm.NewNode() - l := p2p.NewDefaultListener("tcp", config.GetString("node_laddr"), false) + l := p2p.NewDefaultListener("tcp", config.GetString("node_laddr")) node.AddListener(l) node.Start() @@ -69,7 +68,7 @@ func init() { chainID = config.GetString("chain_id") // Save new priv_validator file. - priv := &state.PrivValidator{ + priv := &types.PrivValidator{ Address: user[0].Address, PubKey: acm.PubKeyEd25519(user[0].PubKey.(acm.PubKeyEd25519)), PrivKey: acm.PrivKeyEd25519(user[0].PrivKey.(acm.PrivKeyEd25519)), @@ -126,10 +125,10 @@ func getNonce(t *testing.T, typ string, addr []byte) int { if err != nil { t.Fatal(err) } - if ac == nil { + if ac.Account == nil { return 0 } - return ac.Sequence + return ac.Account.Sequence } // get the account @@ -139,7 +138,7 @@ func getAccount(t *testing.T, typ string, addr []byte) *acm.Account { if err != nil { t.Fatal(err) } - return ac + return ac.Account } // sign transaction @@ -149,22 +148,22 @@ func signTx(t *testing.T, typ string, tx types.Tx, privAcc *acm.PrivAccount) typ if err != nil { t.Fatal(err) } - return signedTx + return signedTx.Tx } // broadcast transaction -func broadcastTx(t *testing.T, typ string, tx types.Tx) *ctypes.Receipt { +func broadcastTx(t *testing.T, typ string, tx types.Tx) ctypes.Receipt { client := clients[typ] rec, err := client.BroadcastTx(tx) if err != nil { t.Fatal(err) } mempoolCount += 1 - return rec + return rec.Receipt } // dump all storage for an account. currently unused -func dumpStorage(t *testing.T, addr []byte) ctypes.ResponseDumpStorage { +func dumpStorage(t *testing.T, addr []byte) ctypes.ResultDumpStorage { client := clients["HTTP"] resp, err := client.DumpStorage(addr) if err != nil { @@ -213,7 +212,7 @@ func getNameRegEntry(t *testing.T, typ string, name string) *types.NameRegEntry if err != nil { t.Fatal(err) } - return entry + return entry.Entry } //-------------------------------------------------------------------------------- diff --git a/rpc/test/tests.go b/rpc/test/tests.go index ba57dc12..2d69f933 100644 --- a/rpc/test/tests.go +++ b/rpc/test/tests.go @@ -28,7 +28,7 @@ func testGenPriv(t *testing.T, typ string) { if err != nil { t.Fatal(err) } - if len(privAcc.Address) == 0 { + if len(privAcc.PrivAccount.Address) == 0 { t.Fatal("Failed to generate an address") } } diff --git a/rpc/test/ws_helpers.go b/rpc/test/ws_helpers.go index 10617693..9ba5c1f2 100644 --- a/rpc/test/ws_helpers.go +++ b/rpc/test/ws_helpers.go @@ -2,7 +2,6 @@ package rpctest import ( "bytes" - "encoding/json" "fmt" "net/http" "testing" @@ -10,6 +9,7 @@ import ( "github.com/tendermint/tendermint/Godeps/_workspace/src/github.com/gorilla/websocket" _ "github.com/tendermint/tendermint/config/tendermint_test" + ctypes "github.com/tendermint/tendermint/rpc/core/types" "github.com/tendermint/tendermint/rpc/types" "github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/wire" @@ -75,14 +75,14 @@ func waitForEvent(t *testing.T, con *websocket.Conn, eventid string, dieOnTimeou } else { // if the event id isnt what we're waiting on // ignore it - var response struct { - Result rpctypes.RPCEventResult `json:"result"` - } - if err := json.Unmarshal(p, &response); err != nil { + var response ctypes.Response + var err error + wire.ReadJSON(&response, p, &err) + if err != nil { errCh <- err break } - if response.Result.Event == eventid { + if response.Result.(*ctypes.ResultEvent).Event == eventid { goodCh <- p break } @@ -109,6 +109,7 @@ func waitForEvent(t *testing.T, con *websocket.Conn, eventid string, dieOnTimeou // run the check err := check(eventid, p) if err != nil { + panic(err) t.Fatal(err) } } else { @@ -124,15 +125,7 @@ func waitForEvent(t *testing.T, con *websocket.Conn, eventid string, dieOnTimeou func unmarshalResponseNewBlock(b []byte) (*types.Block, error) { // unmarshall and assert somethings - var response struct { - JSONRPC string `json:"jsonrpc"` - Id string `json:"id"` - Result struct { - Event string `json:"event"` - Data *types.Block `json:"data"` - } `json:"result"` - Error string `json:"error"` - } + var response ctypes.Response var err error wire.ReadJSON(&response, b, &err) if err != nil { @@ -141,7 +134,7 @@ func unmarshalResponseNewBlock(b []byte) (*types.Block, error) { if response.Error != "" { return nil, fmt.Errorf(response.Error) } - block := response.Result.Data + block := response.Result.(*ctypes.ResultEvent).Data.(types.EventDataNewBlock).Block return block, nil } @@ -192,15 +185,7 @@ func unmarshalValidateBlockchain(t *testing.T, con *websocket.Conn, eid string) func unmarshalValidateSend(amt int64, toAddr []byte) func(string, []byte) error { return func(eid string, b []byte) error { // unmarshal and assert correctness - var response struct { - JSONRPC string `json:"jsonrpc"` - Id string `json:"id"` - Result struct { - Event string `json:"event"` - Data types.EventMsgTx `json:"data"` - } `json:"result"` - Error string `json:"error"` - } + var response ctypes.Response var err error wire.ReadJSON(&response, b, &err) if err != nil { @@ -209,39 +194,27 @@ func unmarshalValidateSend(amt int64, toAddr []byte) func(string, []byte) error if response.Error != "" { return fmt.Errorf(response.Error) } - if eid != response.Result.Event { - return fmt.Errorf("Eventid is not correct. Got %s, expected %s", response.Result.Event, eid) + if eid != response.Result.(*ctypes.ResultEvent).Event { + return fmt.Errorf("Eventid is not correct. Got %s, expected %s", response.Result.(*ctypes.ResultEvent).Event, eid) } - tx := response.Result.Data.Tx.(*types.SendTx) - if bytes.Compare(tx.Inputs[0].Address, user[0].Address) != 0 { + tx := response.Result.(*ctypes.ResultEvent).Data.(types.EventDataTx).Tx.(*types.SendTx) + if !bytes.Equal(tx.Inputs[0].Address, user[0].Address) { return fmt.Errorf("Senders do not match up! Got %x, expected %x", tx.Inputs[0].Address, user[0].Address) } if tx.Inputs[0].Amount != amt { return fmt.Errorf("Amt does not match up! Got %d, expected %d", tx.Inputs[0].Amount, amt) } - if bytes.Compare(tx.Outputs[0].Address, toAddr) != 0 { + if !bytes.Equal(tx.Outputs[0].Address, toAddr) { return fmt.Errorf("Receivers do not match up! Got %x, expected %x", tx.Outputs[0].Address, user[0].Address) } return nil } } -func unmarshalValidateCall(amt int64, returnCode []byte) func(string, []byte) error { +func unmarshalValidateTx(amt int64, returnCode []byte) func(string, []byte) error { return func(eid string, b []byte) error { // unmarshall and assert somethings - var response struct { - JSONRPC string `json:"jsonrpc"` - Id string `json:"id"` - Result struct { - Event string `json:"event"` - Data struct { - Tx types.CallTx `json:"tx"` - Return []byte `json:"return"` - Exception string `json:"exception"` - } `json:"data"` - } `json:"result"` - Error string `json:"error"` - } + var response ctypes.Response var err error wire.ReadJSON(&response, b, &err) if err != nil { @@ -250,36 +223,31 @@ func unmarshalValidateCall(amt int64, returnCode []byte) func(string, []byte) er if response.Error != "" { return fmt.Errorf(response.Error) } - if response.Result.Data.Exception != "" { - return fmt.Errorf(response.Result.Data.Exception) + var data = response.Result.(*ctypes.ResultEvent).Data.(types.EventDataTx) + if data.Exception != "" { + return fmt.Errorf(data.Exception) } - tx := response.Result.Data.Tx - if bytes.Compare(tx.Input.Address, user[0].Address) != 0 { - return fmt.Errorf("Senders do not match up! Got %x, expected %x", tx.Input.Address, user[0].Address) + tx := data.Tx.(*types.CallTx) + if !bytes.Equal(tx.Input.Address, user[0].Address) { + return fmt.Errorf("Senders do not match up! Got %x, expected %x", + tx.Input.Address, user[0].Address) } if tx.Input.Amount != amt { - return fmt.Errorf("Amt does not match up! Got %d, expected %d", tx.Input.Amount, amt) + return fmt.Errorf("Amt does not match up! Got %d, expected %d", + tx.Input.Amount, amt) } - ret := response.Result.Data.Return - if bytes.Compare(ret, returnCode) != 0 { - return fmt.Errorf("Call did not return correctly. Got %x, expected %x", ret, returnCode) + ret := data.Return + if !bytes.Equal(ret, returnCode) { + return fmt.Errorf("Tx did not return correctly. Got %x, expected %x", ret, returnCode) } return nil } } -func unmarshalValidateCallCall(origin, returnCode []byte, txid *[]byte) func(string, []byte) error { +func unmarshalValidateCall(origin, returnCode []byte, txid *[]byte) func(string, []byte) error { return func(eid string, b []byte) error { // unmarshall and assert somethings - var response struct { - JSONRPC string `json:"jsonrpc"` - Id string `json:"id"` - Result struct { - Event string `json:"event"` - Data types.EventMsgCall `json:"data"` - } `json:"result"` - Error string `json:"error"` - } + var response ctypes.Response var err error wire.ReadJSON(&response, b, &err) if err != nil { @@ -288,18 +256,21 @@ func unmarshalValidateCallCall(origin, returnCode []byte, txid *[]byte) func(str if response.Error != "" { return fmt.Errorf(response.Error) } - if response.Result.Data.Exception != "" { - return fmt.Errorf(response.Result.Data.Exception) + var data = response.Result.(*ctypes.ResultEvent).Data.(types.EventDataCall) + if data.Exception != "" { + return fmt.Errorf(data.Exception) } - if bytes.Compare(response.Result.Data.Origin, origin) != 0 { - return fmt.Errorf("Origin does not match up! Got %x, expected %x", response.Result.Data.Origin, origin) + if !bytes.Equal(data.Origin, origin) { + return fmt.Errorf("Origin does not match up! Got %x, expected %x", + data.Origin, origin) } - ret := response.Result.Data.Return - if bytes.Compare(ret, returnCode) != 0 { + ret := data.Return + if !bytes.Equal(ret, returnCode) { return fmt.Errorf("Call did not return correctly. Got %x, expected %x", ret, returnCode) } - if bytes.Compare(response.Result.Data.TxID, *txid) != 0 { - return fmt.Errorf("TxIDs do not match up! Got %x, expected %x", response.Result.Data.TxID, *txid) + if !bytes.Equal(data.TxID, *txid) { + return fmt.Errorf("TxIDs do not match up! Got %x, expected %x", + data.TxID, *txid) } return nil } diff --git a/rpc/types/types.go b/rpc/types/types.go index 47cea1c5..4f7ee208 100644 --- a/rpc/types/types.go +++ b/rpc/types/types.go @@ -25,9 +25,3 @@ func NewRPCResponse(id string, res interface{}, err string) RPCResponse { Error: err, } } - -// Goes in the Result field of an RPCResponse. -type RPCEventResult struct { - Event string `json:"event"` - Data interface{} `json:"data"` -} diff --git a/state/execution.go b/state/execution.go index b9004c32..b14b8d3c 100644 --- a/state/execution.go +++ b/state/execution.go @@ -101,8 +101,8 @@ func execBlock(s *State, block *types.Block, blockPartsHeader types.PartSetHeade // If any unbonding periods are over, // reward account with bonded coins. - toRelease := []*Validator{} - s.UnbondingValidators.Iterate(func(index int, val *Validator) bool { + toRelease := []*types.Validator{} + s.UnbondingValidators.Iterate(func(index int, val *types.Validator) bool { if val.UnbondHeight+unbondingPeriodBlocks < block.Height { toRelease = append(toRelease, val) } @@ -114,8 +114,8 @@ func execBlock(s *State, block *types.Block, blockPartsHeader types.PartSetHeade // If any validators haven't signed in a while, // unbond them, they have timed out. - toTimeout := []*Validator{} - s.BondedValidators.Iterate(func(index int, val *Validator) bool { + toTimeout := []*types.Validator{} + s.BondedValidators.Iterate(func(index int, val *types.Validator) bool { lastActivityHeight := MaxInt(val.BondHeight, val.LastCommitHeight) if lastActivityHeight+validatorTimeoutBlocks < block.Height { log.Notice("Validator timeout", "validator", val, "height", block.Height) @@ -337,11 +337,11 @@ func ExecTx(blockCache *BlockCache, tx types.Tx, runCall bool, evc events.Fireab // if the evc is nil, nothing will happen if evc != nil { for _, i := range tx.Inputs { - evc.FireEvent(types.EventStringAccInput(i.Address), types.EventMsgTx{tx, nil, ""}) + evc.FireEvent(types.EventStringAccInput(i.Address), types.EventDataTx{tx, nil, ""}) } for _, o := range tx.Outputs { - evc.FireEvent(types.EventStringAccOutput(o.Address), types.EventMsgTx{tx, nil, ""}) + evc.FireEvent(types.EventStringAccOutput(o.Address), types.EventDataTx{tx, nil, ""}) } } return nil @@ -494,8 +494,8 @@ func ExecTx(blockCache *BlockCache, tx types.Tx, runCall bool, evc events.Fireab if err != nil { exception = err.Error() } - evc.FireEvent(types.EventStringAccInput(tx.Input.Address), types.EventMsgTx{tx, ret, exception}) - evc.FireEvent(types.EventStringAccOutput(tx.Address), types.EventMsgTx{tx, ret, exception}) + evc.FireEvent(types.EventStringAccInput(tx.Input.Address), types.EventDataTx{tx, ret, exception}) + evc.FireEvent(types.EventStringAccOutput(tx.Address), types.EventDataTx{tx, ret, exception}) } } else { // The mempool does not call txs until @@ -691,7 +691,7 @@ func ExecTx(blockCache *BlockCache, tx types.Tx, runCall bool, evc events.Fireab blockCache.UpdateAccount(acc) } // Add ValidatorInfo - _s.SetValidatorInfo(&ValidatorInfo{ + _s.SetValidatorInfo(&types.ValidatorInfo{ Address: tx.PubKey.Address(), PubKey: tx.PubKey, UnbondTo: tx.UnbondTo, @@ -699,7 +699,7 @@ func ExecTx(blockCache *BlockCache, tx types.Tx, runCall bool, evc events.Fireab FirstBondAmount: outTotal, }) // Add Validator - added := _s.BondedValidators.Add(&Validator{ + added := _s.BondedValidators.Add(&types.Validator{ Address: tx.PubKey.Address(), PubKey: tx.PubKey, BondHeight: _s.LastBlockHeight + 1, @@ -893,7 +893,7 @@ func ExecTx(blockCache *BlockCache, tx types.Tx, runCall bool, evc events.Fireab } if evc != nil { - evc.FireEvent(types.EventStringAccInput(tx.Input.Address), types.EventMsgTx{tx, nil, ""}) + evc.FireEvent(types.EventStringAccInput(tx.Input.Address), types.EventDataTx{tx, nil, ""}) evc.FireEvent(types.EventStringPermissions(ptypes.PermFlagToString(permFlag)), tx) } @@ -981,3 +981,14 @@ func hasBondOrSendPermission(state AccountGetter, accs map[string]*acm.Account) } return true } + +//----------------------------------------------------------------------------- + +type InvalidTxError struct { + Tx types.Tx + Reason error +} + +func (txErr InvalidTxError) Error() string { + return Fmt("Invalid tx: [%v] reason: [%v]", txErr.Tx, txErr.Reason) +} diff --git a/state/genesis.go b/state/genesis.go deleted file mode 100644 index ad9752e2..00000000 --- a/state/genesis.go +++ /dev/null @@ -1,175 +0,0 @@ -package state - -import ( - "io/ioutil" - "time" - - acm "github.com/tendermint/tendermint/account" - . "github.com/tendermint/tendermint/common" - dbm "github.com/tendermint/tendermint/db" - "github.com/tendermint/tendermint/merkle" - ptypes "github.com/tendermint/tendermint/permission/types" - "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/wire" -) - -//------------------------------------------------------------ -// we store the gendoc in the db - -var GenDocKey = []byte("GenDocKey") - -//------------------------------------------------------------ -// core types for a genesis definition - -type BasicAccount struct { - Address []byte `json:"address"` - Amount int64 `json:"amount"` -} - -type GenesisAccount struct { - Address []byte `json:"address"` - Amount int64 `json:"amount"` - Name string `json:"name"` - Permissions *ptypes.AccountPermissions `json:"permissions"` -} - -type GenesisValidator struct { - PubKey acm.PubKeyEd25519 `json:"pub_key"` - Amount int64 `json:"amount"` - Name string `json:"name"` - UnbondTo []BasicAccount `json:"unbond_to"` -} - -type GenesisParams struct { - GlobalPermissions *ptypes.AccountPermissions `json:"global_permissions"` -} - -type GenesisDoc struct { - GenesisTime time.Time `json:"genesis_time"` - ChainID string `json:"chain_id"` - Params *GenesisParams `json:"params"` - Accounts []GenesisAccount `json:"accounts"` - Validators []GenesisValidator `json:"validators"` -} - -//------------------------------------------------------------ -// Make genesis state from file - -func GenesisDocFromJSON(jsonBlob []byte) (genState *GenesisDoc) { - var err error - wire.ReadJSONPtr(&genState, jsonBlob, &err) - if err != nil { - Exit(Fmt("Couldn't read GenesisDoc: %v", err)) - } - return -} - -func MakeGenesisStateFromFile(db dbm.DB, genDocFile string) (*GenesisDoc, *State) { - jsonBlob, err := ioutil.ReadFile(genDocFile) - if err != nil { - Exit(Fmt("Couldn't read GenesisDoc file: %v", err)) - } - genDoc := GenesisDocFromJSON(jsonBlob) - return genDoc, MakeGenesisState(db, genDoc) -} - -func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State { - if len(genDoc.Validators) == 0 { - Exit(Fmt("The genesis file has no validators")) - } - - if genDoc.GenesisTime.IsZero() { - genDoc.GenesisTime = time.Now() - } - - // Make accounts state tree - accounts := merkle.NewIAVLTree(wire.BasicCodec, acm.AccountCodec, defaultAccountsCacheCapacity, db) - for _, genAcc := range genDoc.Accounts { - perm := ptypes.ZeroAccountPermissions - if genAcc.Permissions != nil { - perm = *genAcc.Permissions - } - acc := &acm.Account{ - Address: genAcc.Address, - PubKey: nil, - Sequence: 0, - Balance: genAcc.Amount, - Permissions: perm, - } - accounts.Set(acc.Address, acc) - } - - // global permissions are saved as the 0 address - // so they are included in the accounts tree - globalPerms := ptypes.DefaultAccountPermissions - if genDoc.Params != nil && genDoc.Params.GlobalPermissions != nil { - globalPerms = *genDoc.Params.GlobalPermissions - // XXX: make sure the set bits are all true - // Without it the HasPermission() functions will fail - globalPerms.Base.SetBit = ptypes.AllPermFlags - } - - permsAcc := &acm.Account{ - Address: ptypes.GlobalPermissionsAddress, - PubKey: nil, - Sequence: 0, - Balance: 1337, - Permissions: globalPerms, - } - accounts.Set(permsAcc.Address, permsAcc) - - // Make validatorInfos state tree && validators slice - validatorInfos := merkle.NewIAVLTree(wire.BasicCodec, ValidatorInfoCodec, 0, db) - validators := make([]*Validator, len(genDoc.Validators)) - for i, val := range genDoc.Validators { - pubKey := val.PubKey - address := pubKey.Address() - - // Make ValidatorInfo - valInfo := &ValidatorInfo{ - Address: address, - PubKey: pubKey, - UnbondTo: make([]*types.TxOutput, len(val.UnbondTo)), - FirstBondHeight: 0, - FirstBondAmount: val.Amount, - } - for i, unbondTo := range val.UnbondTo { - valInfo.UnbondTo[i] = &types.TxOutput{ - Address: unbondTo.Address, - Amount: unbondTo.Amount, - } - } - validatorInfos.Set(address, valInfo) - - // Make validator - validators[i] = &Validator{ - Address: address, - PubKey: pubKey, - VotingPower: val.Amount, - } - } - - // Make namereg tree - nameReg := merkle.NewIAVLTree(wire.BasicCodec, NameRegCodec, 0, db) - // TODO: add names, contracts to genesis.json - - // IAVLTrees must be persisted before copy operations. - accounts.Save() - validatorInfos.Save() - nameReg.Save() - - return &State{ - DB: db, - ChainID: genDoc.ChainID, - LastBlockHeight: 0, - LastBlockHash: nil, - LastBlockParts: types.PartSetHeader{}, - LastBlockTime: genDoc.GenesisTime, - BondedValidators: NewValidatorSet(validators), - LastBondedValidators: NewValidatorSet(nil), - UnbondingValidators: NewValidatorSet(nil), - accounts: accounts, - validatorInfos: validatorInfos, - nameReg: nameReg, - } -} diff --git a/state/genesis_test.go b/state/genesis_test.go index 27b5522a..dfa66339 100644 --- a/state/genesis_test.go +++ b/state/genesis_test.go @@ -8,6 +8,7 @@ import ( tdb "github.com/tendermint/tendermint/db" ptypes "github.com/tendermint/tendermint/permission/types" + . "github.com/tendermint/tendermint/state/types" ) var chain_id = "lone_ranger" diff --git a/state/permissions_test.go b/state/permissions_test.go index 6ac9fd40..057b1700 100644 --- a/state/permissions_test.go +++ b/state/permissions_test.go @@ -12,6 +12,7 @@ import ( dbm "github.com/tendermint/tendermint/db" "github.com/tendermint/tendermint/events" ptypes "github.com/tendermint/tendermint/permission/types" + . "github.com/tendermint/tendermint/state/types" "github.com/tendermint/tendermint/types" ) @@ -1073,9 +1074,9 @@ func execTxWaitEvent(t *testing.T, blockCache *BlockCache, tx types.Tx, eventid } switch ev := msg.(type) { - case types.EventMsgTx: + case types.EventDataTx: return ev, ev.Exception - case types.EventMsgCall: + case types.EventDataCall: return ev, ev.Exception case string: return nil, ev @@ -1118,7 +1119,7 @@ func testSNativeCALL(t *testing.T, expectPass bool, blockCache *BlockCache, doug if exception != "" { t.Fatal("Unexpected exception", exception) } - evv := ev.(types.EventMsgCall) + evv := ev.(types.EventDataCall) ret := evv.Return if err := f(ret); err != nil { t.Fatal(err) diff --git a/state/state.go b/state/state.go index 63782be4..5e876796 100644 --- a/state/state.go +++ b/state/state.go @@ -3,15 +3,18 @@ package state import ( "bytes" "io" + "io/ioutil" "time" acm "github.com/tendermint/tendermint/account" - "github.com/tendermint/tendermint/wire" . "github.com/tendermint/tendermint/common" dbm "github.com/tendermint/tendermint/db" "github.com/tendermint/tendermint/events" "github.com/tendermint/tendermint/merkle" + ptypes "github.com/tendermint/tendermint/permission/types" + . "github.com/tendermint/tendermint/state/types" "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/wire" ) var ( @@ -32,9 +35,9 @@ type State struct { LastBlockHash []byte LastBlockParts types.PartSetHeader LastBlockTime time.Time - BondedValidators *ValidatorSet - LastBondedValidators *ValidatorSet - UnbondingValidators *ValidatorSet + BondedValidators *types.ValidatorSet + LastBondedValidators *types.ValidatorSet + UnbondingValidators *types.ValidatorSet accounts merkle.Tree // Shouldn't be accessed directly. validatorInfos merkle.Tree // Shouldn't be accessed directly. nameReg merkle.Tree // Shouldn't be accessed directly. @@ -54,14 +57,14 @@ func LoadState(db dbm.DB) *State { s.LastBlockHash = wire.ReadByteSlice(r, n, err) s.LastBlockParts = wire.ReadBinary(types.PartSetHeader{}, r, n, err).(types.PartSetHeader) s.LastBlockTime = wire.ReadTime(r, n, err) - s.BondedValidators = wire.ReadBinary(&ValidatorSet{}, r, n, err).(*ValidatorSet) - s.LastBondedValidators = wire.ReadBinary(&ValidatorSet{}, r, n, err).(*ValidatorSet) - s.UnbondingValidators = wire.ReadBinary(&ValidatorSet{}, r, n, err).(*ValidatorSet) + s.BondedValidators = wire.ReadBinary(&types.ValidatorSet{}, r, n, err).(*types.ValidatorSet) + s.LastBondedValidators = wire.ReadBinary(&types.ValidatorSet{}, r, n, err).(*types.ValidatorSet) + s.UnbondingValidators = wire.ReadBinary(&types.ValidatorSet{}, r, n, err).(*types.ValidatorSet) accountsHash := wire.ReadByteSlice(r, n, err) s.accounts = merkle.NewIAVLTree(wire.BasicCodec, acm.AccountCodec, defaultAccountsCacheCapacity, db) s.accounts.Load(accountsHash) validatorInfosHash := wire.ReadByteSlice(r, n, err) - s.validatorInfos = merkle.NewIAVLTree(wire.BasicCodec, ValidatorInfoCodec, 0, db) + s.validatorInfos = merkle.NewIAVLTree(wire.BasicCodec, types.ValidatorInfoCodec, 0, db) s.validatorInfos.Load(validatorInfosHash) nameRegHash := wire.ReadByteSlice(r, n, err) s.nameReg = merkle.NewIAVLTree(wire.BasicCodec, NameRegCodec, 0, db) @@ -200,18 +203,18 @@ func (s *State) SetAccounts(accounts merkle.Tree) { // The returned ValidatorInfo is a copy, so mutating it // has no side effects. -func (s *State) GetValidatorInfo(address []byte) *ValidatorInfo { +func (s *State) GetValidatorInfo(address []byte) *types.ValidatorInfo { _, valInfo := s.validatorInfos.Get(address) if valInfo == nil { return nil } - return valInfo.(*ValidatorInfo).Copy() + return valInfo.(*types.ValidatorInfo).Copy() } // Returns false if new, true if updated. // The valInfo is copied before setting, so mutating it // afterwards has no side effects. -func (s *State) SetValidatorInfo(valInfo *ValidatorInfo) (updated bool) { +func (s *State) SetValidatorInfo(valInfo *types.ValidatorInfo) (updated bool) { return s.validatorInfos.Set(valInfo.Address, valInfo.Copy()) } @@ -219,7 +222,7 @@ func (s *State) GetValidatorInfos() merkle.Tree { return s.validatorInfos.Copy() } -func (s *State) unbondValidator(val *Validator) { +func (s *State) unbondValidator(val *types.Validator) { // Move validator to UnbondingValidators val, removed := s.BondedValidators.Remove(val.Address) if !removed { @@ -232,7 +235,7 @@ func (s *State) unbondValidator(val *Validator) { } } -func (s *State) rebondValidator(val *Validator) { +func (s *State) rebondValidator(val *types.Validator) { // Move validator to BondingValidators val, removed := s.UnbondingValidators.Remove(val.Address) if !removed { @@ -245,7 +248,7 @@ func (s *State) rebondValidator(val *Validator) { } } -func (s *State) releaseValidator(val *Validator) { +func (s *State) releaseValidator(val *types.Validator) { // Update validatorInfo valInfo := s.GetValidatorInfo(val.Address) if valInfo == nil { @@ -271,7 +274,7 @@ func (s *State) releaseValidator(val *Validator) { } } -func (s *State) destroyValidator(val *Validator) { +func (s *State) destroyValidator(val *types.Validator) { // Update validatorInfo valInfo := s.GetValidatorInfo(val.Address) if valInfo == nil { @@ -360,12 +363,114 @@ func (s *State) SetFireable(evc events.Fireable) { } //----------------------------------------------------------------------------- +// Genesis -type InvalidTxError struct { - Tx types.Tx - Reason error +func MakeGenesisStateFromFile(db dbm.DB, genDocFile string) (*GenesisDoc, *State) { + jsonBlob, err := ioutil.ReadFile(genDocFile) + if err != nil { + Exit(Fmt("Couldn't read GenesisDoc file: %v", err)) + } + genDoc := GenesisDocFromJSON(jsonBlob) + return genDoc, MakeGenesisState(db, genDoc) } -func (txErr InvalidTxError) Error() string { - return Fmt("Invalid tx: [%v] reason: [%v]", txErr.Tx, txErr.Reason) +func MakeGenesisState(db dbm.DB, genDoc *GenesisDoc) *State { + if len(genDoc.Validators) == 0 { + Exit(Fmt("The genesis file has no validators")) + } + + if genDoc.GenesisTime.IsZero() { + genDoc.GenesisTime = time.Now() + } + + // Make accounts state tree + accounts := merkle.NewIAVLTree(wire.BasicCodec, acm.AccountCodec, defaultAccountsCacheCapacity, db) + for _, genAcc := range genDoc.Accounts { + perm := ptypes.ZeroAccountPermissions + if genAcc.Permissions != nil { + perm = *genAcc.Permissions + } + acc := &acm.Account{ + Address: genAcc.Address, + PubKey: nil, + Sequence: 0, + Balance: genAcc.Amount, + Permissions: perm, + } + accounts.Set(acc.Address, acc) + } + + // global permissions are saved as the 0 address + // so they are included in the accounts tree + globalPerms := ptypes.DefaultAccountPermissions + if genDoc.Params != nil && genDoc.Params.GlobalPermissions != nil { + globalPerms = *genDoc.Params.GlobalPermissions + // XXX: make sure the set bits are all true + // Without it the HasPermission() functions will fail + globalPerms.Base.SetBit = ptypes.AllPermFlags + } + + permsAcc := &acm.Account{ + Address: ptypes.GlobalPermissionsAddress, + PubKey: nil, + Sequence: 0, + Balance: 1337, + Permissions: globalPerms, + } + accounts.Set(permsAcc.Address, permsAcc) + + // Make validatorInfos state tree && validators slice + validatorInfos := merkle.NewIAVLTree(wire.BasicCodec, types.ValidatorInfoCodec, 0, db) + validators := make([]*types.Validator, len(genDoc.Validators)) + for i, val := range genDoc.Validators { + pubKey := val.PubKey + address := pubKey.Address() + + // Make ValidatorInfo + valInfo := &types.ValidatorInfo{ + Address: address, + PubKey: pubKey, + UnbondTo: make([]*types.TxOutput, len(val.UnbondTo)), + FirstBondHeight: 0, + FirstBondAmount: val.Amount, + } + for i, unbondTo := range val.UnbondTo { + valInfo.UnbondTo[i] = &types.TxOutput{ + Address: unbondTo.Address, + Amount: unbondTo.Amount, + } + } + validatorInfos.Set(address, valInfo) + + // Make validator + validators[i] = &types.Validator{ + Address: address, + PubKey: pubKey, + VotingPower: val.Amount, + } + } + + // Make namereg tree + nameReg := merkle.NewIAVLTree(wire.BasicCodec, NameRegCodec, 0, db) + // TODO: add names, contracts to genesis.json + + // IAVLTrees must be persisted before copy operations. + accounts.Save() + validatorInfos.Save() + nameReg.Save() + + return &State{ + DB: db, + ChainID: genDoc.ChainID, + LastBlockHeight: 0, + LastBlockHash: nil, + LastBlockParts: types.PartSetHeader{}, + LastBlockTime: genDoc.GenesisTime, + BondedValidators: types.NewValidatorSet(validators), + LastBondedValidators: types.NewValidatorSet(nil), + UnbondingValidators: types.NewValidatorSet(nil), + accounts: accounts, + validatorInfos: validatorInfos, + nameReg: nameReg, + } } diff --git a/state/test.go b/state/test.go index 65035c82..90d5003d 100644 --- a/state/test.go +++ b/state/test.go @@ -1,28 +1,17 @@ package state import ( - "bytes" "sort" + "time" acm "github.com/tendermint/tendermint/account" . "github.com/tendermint/tendermint/common" dbm "github.com/tendermint/tendermint/db" ptypes "github.com/tendermint/tendermint/permission/types" + . "github.com/tendermint/tendermint/state/types" "github.com/tendermint/tendermint/types" - - "io/ioutil" - "os" - "time" ) -func Tempfile(prefix string) (*os.File, string) { - file, err := ioutil.TempFile("", prefix) - if err != nil { - PanicCrisis(err) - } - return file, file.Name() -} - func RandAccount(randBalance bool, minBalance int64) (*acm.Account, *acm.PrivAccount) { privAccount := acm.GenPrivAccount() perms := ptypes.DefaultAccountPermissions @@ -39,37 +28,7 @@ func RandAccount(randBalance bool, minBalance int64) (*acm.Account, *acm.PrivAcc return acc, privAccount } -func RandValidator(randBonded bool, minBonded int64) (*ValidatorInfo, *Validator, *PrivValidator) { - privVal := GenPrivValidator() - _, tempFilePath := Tempfile("priv_validator_") - privVal.SetFile(tempFilePath) - bonded := minBonded - if randBonded { - bonded += int64(RandUint32()) - } - valInfo := &ValidatorInfo{ - Address: privVal.Address, - PubKey: privVal.PubKey, - UnbondTo: []*types.TxOutput{&types.TxOutput{ - Amount: bonded, - Address: privVal.Address, - }}, - FirstBondHeight: 0, - FirstBondAmount: bonded, - } - val := &Validator{ - Address: valInfo.Address, - PubKey: valInfo.PubKey, - BondHeight: 0, - UnbondHeight: 0, - LastCommitHeight: 0, - VotingPower: valInfo.FirstBondAmount, - Accum: 0, - } - return valInfo, val, privVal -} - -func RandGenesisDoc(numAccounts int, randBalance bool, minBalance int64, numValidators int, randBonded bool, minBonded int64) (*GenesisDoc, []*acm.PrivAccount, []*PrivValidator) { +func RandGenesisDoc(numAccounts int, randBalance bool, minBalance int64, numValidators int, randBonded bool, minBonded int64) (*GenesisDoc, []*acm.PrivAccount, []*types.PrivValidator) { accounts := make([]GenesisAccount, numAccounts) privAccounts := make([]*acm.PrivAccount, numAccounts) defaultPerms := ptypes.DefaultAccountPermissions @@ -83,9 +42,9 @@ func RandGenesisDoc(numAccounts int, randBalance bool, minBalance int64, numVali privAccounts[i] = privAccount } validators := make([]GenesisValidator, numValidators) - privValidators := make([]*PrivValidator, numValidators) + privValidators := make([]*types.PrivValidator, numValidators) for i := 0; i < numValidators; i++ { - valInfo, _, privVal := RandValidator(randBonded, minBonded) + valInfo, _, privVal := types.RandValidator(randBonded, minBonded) validators[i] = GenesisValidator{ PubKey: valInfo.PubKey, Amount: valInfo.FirstBondAmount, @@ -98,7 +57,7 @@ func RandGenesisDoc(numAccounts int, randBalance bool, minBalance int64, numVali } privValidators[i] = privVal } - sort.Sort(PrivValidatorsByAddress(privValidators)) + sort.Sort(types.PrivValidatorsByAddress(privValidators)) return &GenesisDoc{ GenesisTime: time.Now(), ChainID: "tendermint_test", @@ -108,28 +67,10 @@ func RandGenesisDoc(numAccounts int, randBalance bool, minBalance int64, numVali } -func RandGenesisState(numAccounts int, randBalance bool, minBalance int64, numValidators int, randBonded bool, minBonded int64) (*State, []*acm.PrivAccount, []*PrivValidator) { +func RandGenesisState(numAccounts int, randBalance bool, minBalance int64, numValidators int, randBonded bool, minBonded int64) (*State, []*acm.PrivAccount, []*types.PrivValidator) { db := dbm.NewMemDB() genDoc, privAccounts, privValidators := RandGenesisDoc(numAccounts, randBalance, minBalance, numValidators, randBonded, minBonded) s0 := MakeGenesisState(db, genDoc) s0.Save() return s0, privAccounts, privValidators } - -//------------------------------------- - -type PrivValidatorsByAddress []*PrivValidator - -func (pvs PrivValidatorsByAddress) Len() int { - return len(pvs) -} - -func (pvs PrivValidatorsByAddress) Less(i, j int) bool { - return bytes.Compare(pvs[i].Address, pvs[j].Address) == -1 -} - -func (pvs PrivValidatorsByAddress) Swap(i, j int) { - it := pvs[i] - pvs[i] = pvs[j] - pvs[j] = it -} diff --git a/state/tx_cache.go b/state/tx_cache.go index c99bf295..4d7f20c1 100644 --- a/state/tx_cache.go +++ b/state/tx_cache.go @@ -12,7 +12,7 @@ type TxCache struct { backend *BlockCache accounts map[Word256]vmAccountInfo storages map[Tuple256]Word256 - logs []*vm.Log + logs []types.EventDataLog } func NewTxCache(backend *BlockCache) *TxCache { @@ -20,7 +20,7 @@ func NewTxCache(backend *BlockCache) *TxCache { backend: backend, accounts: make(map[Word256]vmAccountInfo), storages: make(map[Tuple256]Word256), - logs: make([]*vm.Log, 0), + logs: make([]types.EventDataLog, 0), } } @@ -138,7 +138,7 @@ func (cache *TxCache) Sync() { } } -func (cache *TxCache) AddLog(log *vm.Log) { +func (cache *TxCache) AddLog(log types.EventDataLog) { cache.logs = append(cache.logs, log) } diff --git a/state/types/genesis.go b/state/types/genesis.go new file mode 100644 index 00000000..c956286f --- /dev/null +++ b/state/types/genesis.go @@ -0,0 +1,61 @@ +package types + +import ( + "time" + + acm "github.com/tendermint/tendermint/account" + . "github.com/tendermint/tendermint/common" + ptypes "github.com/tendermint/tendermint/permission/types" + "github.com/tendermint/tendermint/wire" +) + +//------------------------------------------------------------ +// we store the gendoc in the db + +var GenDocKey = []byte("GenDocKey") + +//------------------------------------------------------------ +// core types for a genesis definition + +type BasicAccount struct { + Address []byte `json:"address"` + Amount int64 `json:"amount"` +} + +type GenesisAccount struct { + Address []byte `json:"address"` + Amount int64 `json:"amount"` + Name string `json:"name"` + Permissions *ptypes.AccountPermissions `json:"permissions"` +} + +type GenesisValidator struct { + PubKey acm.PubKeyEd25519 `json:"pub_key"` + Amount int64 `json:"amount"` + Name string `json:"name"` + UnbondTo []BasicAccount `json:"unbond_to"` +} + +type GenesisParams struct { + GlobalPermissions *ptypes.AccountPermissions `json:"global_permissions"` +} + +type GenesisDoc struct { + GenesisTime time.Time `json:"genesis_time"` + ChainID string `json:"chain_id"` + Params *GenesisParams `json:"params"` + Accounts []GenesisAccount `json:"accounts"` + Validators []GenesisValidator `json:"validators"` +} + +//------------------------------------------------------------ +// Make genesis state from file + +func GenesisDocFromJSON(jsonBlob []byte) (genState *GenesisDoc) { + var err error + wire.ReadJSONPtr(&genState, jsonBlob, &err) + if err != nil { + Exit(Fmt("Couldn't read GenesisDoc: %v", err)) + } + return +} diff --git a/types/events.go b/types/events.go index 307894ce..d37dc27c 100644 --- a/types/events.go +++ b/types/events.go @@ -2,6 +2,9 @@ package types import ( "fmt" + + . "github.com/tendermint/tendermint/common" + "github.com/tendermint/tendermint/wire" ) // Functions to generate eventId strings @@ -18,15 +21,50 @@ func EventStringDupeout() string { return "Dupeout" } func EventStringNewBlock() string { return "NewBlock" } func EventStringFork() string { return "Fork" } +//---------------------------------------- + +const ( + EventDataTypeNewBlock = byte(0x01) + EventDataTypeFork = byte(0x02) + EventDataTypeTx = byte(0x03) + EventDataTypeCall = byte(0x04) + EventDataTypeLog = byte(0x05) +) + +type EventData interface{} + +var _ = wire.RegisterInterface( + struct{ EventData }{}, + wire.ConcreteType{EventDataNewBlock{}, EventDataTypeNewBlock}, + // wire.ConcreteType{EventDataNewBlock{}, EventDataTypeFork }, + wire.ConcreteType{EventDataTx{}, EventDataTypeTx}, + wire.ConcreteType{EventDataCall{}, EventDataTypeCall}, + wire.ConcreteType{EventDataLog{}, EventDataTypeLog}, +) + // Most event messages are basic types (a block, a transaction) // but some (an input to a call tx or a receive) are more exotic: -type EventMsgTx struct { +type EventDataNewBlock struct { + Block *Block `json:"block"` +} + +// All txs fire EventDataTx, but only CallTx might have Return or Exception +type EventDataTx struct { Tx Tx `json:"tx"` Return []byte `json:"return"` Exception string `json:"exception"` } +// EventDataCall fires when we call a contract, and when a contract calls another contract +type EventDataCall struct { + CallData *CallData `json:"call_data"` + Origin []byte `json:"origin"` + TxID []byte `json:"tx_id"` + Return []byte `json:"return"` + Exception string `json:"exception"` +} + type CallData struct { Caller []byte `json:"caller"` Callee []byte `json:"callee"` @@ -35,10 +73,10 @@ type CallData struct { Gas int64 `json:"gas"` } -type EventMsgCall struct { - CallData *CallData `json:"call_data"` - Origin []byte `json:"origin"` - TxID []byte `json:"tx_id"` - Return []byte `json:"return"` - Exception string `json:"exception"` +// EventDataLog fires when a contract executes the LOG opcode +type EventDataLog struct { + Address Word256 `json:"address"` + Topics []Word256 `json:"topics"` + Data []byte `json:"data"` + Height int64 `json:"height"` } diff --git a/state/priv_validator.go b/types/priv_validator.go similarity index 89% rename from state/priv_validator.go rename to types/priv_validator.go index 3df14622..b4e88064 100644 --- a/state/priv_validator.go +++ b/types/priv_validator.go @@ -1,6 +1,7 @@ -package state +package types import ( + "bytes" "errors" "fmt" "io/ioutil" @@ -8,10 +9,8 @@ import ( "sync" acm "github.com/tendermint/tendermint/account" - "github.com/tendermint/tendermint/wire" . "github.com/tendermint/tendermint/common" - . "github.com/tendermint/tendermint/consensus/types" - "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/wire" "github.com/tendermint/tendermint/Godeps/_workspace/src/github.com/tendermint/ed25519" ) @@ -23,11 +22,11 @@ const ( stepPrecommit = 3 ) -func voteToStep(vote *types.Vote) int8 { +func voteToStep(vote *Vote) int8 { switch vote.Type { - case types.VoteTypePrevote: + case VoteTypePrevote: return stepPrevote - case types.VoteTypePrecommit: + case VoteTypePrecommit: return stepPrecommit default: PanicSanity("Unknown vote type") @@ -104,7 +103,7 @@ func (privVal *PrivValidator) save() { } } -func (privVal *PrivValidator) SignVote(chainID string, vote *types.Vote) error { +func (privVal *PrivValidator) SignVote(chainID string, vote *Vote) error { privVal.mtx.Lock() defer privVal.mtx.Unlock() @@ -135,7 +134,7 @@ func (privVal *PrivValidator) SignVote(chainID string, vote *types.Vote) error { return nil } -func (privVal *PrivValidator) SignVoteUnsafe(chainID string, vote *types.Vote) { +func (privVal *PrivValidator) SignVoteUnsafe(chainID string, vote *Vote) { vote.Signature = privVal.PrivKey.Sign(acm.SignBytes(chainID, vote)).(acm.SignatureEd25519) } @@ -160,7 +159,7 @@ func (privVal *PrivValidator) SignProposal(chainID string, proposal *Proposal) e } } -func (privVal *PrivValidator) SignRebondTx(chainID string, rebondTx *types.RebondTx) error { +func (privVal *PrivValidator) SignRebondTx(chainID string, rebondTx *RebondTx) error { privVal.mtx.Lock() defer privVal.mtx.Unlock() if privVal.LastHeight < rebondTx.Height { @@ -183,3 +182,21 @@ func (privVal *PrivValidator) SignRebondTx(chainID string, rebondTx *types.Rebon func (privVal *PrivValidator) String() string { return fmt.Sprintf("PrivValidator{%X LH:%v, LR:%v, LS:%v}", privVal.Address, privVal.LastHeight, privVal.LastRound, privVal.LastStep) } + +//------------------------------------- + +type PrivValidatorsByAddress []*PrivValidator + +func (pvs PrivValidatorsByAddress) Len() int { + return len(pvs) +} + +func (pvs PrivValidatorsByAddress) Less(i, j int) bool { + return bytes.Compare(pvs[i].Address, pvs[j].Address) == -1 +} + +func (pvs PrivValidatorsByAddress) Swap(i, j int) { + it := pvs[i] + pvs[i] = pvs[j] + pvs[j] = it +} diff --git a/consensus/types/proposal.go b/types/proposal.go similarity index 85% rename from consensus/types/proposal.go rename to types/proposal.go index 54f54f13..78c393f9 100644 --- a/consensus/types/proposal.go +++ b/types/proposal.go @@ -1,4 +1,4 @@ -package consensus +package types import ( "errors" @@ -6,9 +6,8 @@ import ( "io" acm "github.com/tendermint/tendermint/account" - "github.com/tendermint/tendermint/wire" . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/wire" ) var ( @@ -19,12 +18,12 @@ var ( type Proposal struct { Height int `json:"height"` Round int `json:"round"` - BlockPartsHeader types.PartSetHeader `json:"block_parts_header"` + BlockPartsHeader PartSetHeader `json:"block_parts_header"` POLRound int `json:"pol_round"` // -1 if null. Signature acm.SignatureEd25519 `json:"signature"` } -func NewProposal(height int, round int, blockPartsHeader types.PartSetHeader, polRound int) *Proposal { +func NewProposal(height int, round int, blockPartsHeader PartSetHeader, polRound int) *Proposal { return &Proposal{ Height: height, Round: round, diff --git a/consensus/types/proposal_test.go b/types/proposal_test.go similarity index 85% rename from consensus/types/proposal_test.go rename to types/proposal_test.go index 2fd6c9a3..f37c11ee 100644 --- a/consensus/types/proposal_test.go +++ b/types/proposal_test.go @@ -1,4 +1,4 @@ -package consensus +package types import ( "testing" @@ -6,14 +6,13 @@ import ( acm "github.com/tendermint/tendermint/account" . "github.com/tendermint/tendermint/common" _ "github.com/tendermint/tendermint/config/tendermint_test" - "github.com/tendermint/tendermint/types" ) func TestProposalSignable(t *testing.T) { proposal := &Proposal{ Height: 12345, Round: 23456, - BlockPartsHeader: types.PartSetHeader{111, []byte("blockparts")}, + BlockPartsHeader: PartSetHeader{111, []byte("blockparts")}, POLRound: -1, } signBytes := acm.SignBytes(config.GetString("chain_id"), proposal) diff --git a/state/validator.go b/types/validator.go similarity index 96% rename from state/validator.go rename to types/validator.go index dcc95966..dbf4cbde 100644 --- a/state/validator.go +++ b/types/validator.go @@ -1,4 +1,4 @@ -package state +package types import ( "bytes" @@ -6,16 +6,15 @@ import ( "io" acm "github.com/tendermint/tendermint/account" - "github.com/tendermint/tendermint/wire" . "github.com/tendermint/tendermint/common" - "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/wire" ) // Persistent (mostly) static data for each Validator type ValidatorInfo struct { Address []byte `json:"address"` PubKey acm.PubKeyEd25519 `json:"pub_key"` - UnbondTo []*types.TxOutput `json:"unbond_to"` + UnbondTo []*TxOutput `json:"unbond_to"` FirstBondHeight int `json:"first_bond_height"` FirstBondAmount int64 `json:"first_bond_amount"` DestroyedHeight int `json:"destroyed_height"` // If destroyed diff --git a/state/validator_set.go b/types/validator_set.go similarity index 97% rename from state/validator_set.go rename to types/validator_set.go index 7f821d9c..ecf7287a 100644 --- a/state/validator_set.go +++ b/types/validator_set.go @@ -1,4 +1,4 @@ -package state +package types import ( "bytes" @@ -9,7 +9,6 @@ import ( "github.com/tendermint/tendermint/account" . "github.com/tendermint/tendermint/common" "github.com/tendermint/tendermint/merkle" - "github.com/tendermint/tendermint/types" ) // ValidatorSet represent a set of *Validator at a given height. @@ -204,7 +203,7 @@ func (valSet *ValidatorSet) Iterate(fn func(index int, val *Validator) bool) { // Verify that +2/3 of the set had signed the given signBytes func (valSet *ValidatorSet) VerifyValidation(chainID string, - hash []byte, parts types.PartSetHeader, height int, v *types.Validation) error { + hash []byte, parts PartSetHeader, height int, v *Validation) error { if valSet.Size() != len(v.Precommits) { return fmt.Errorf("Invalid validation -- wrong set size: %v vs %v", valSet.Size(), len(v.Precommits)) } @@ -226,7 +225,7 @@ func (valSet *ValidatorSet) VerifyValidation(chainID string, if precommit.Round != round { return fmt.Errorf("Invalid validation -- wrong round: %v vs %v", round, precommit.Round) } - if precommit.Type != types.VoteTypePrecommit { + if precommit.Type != VoteTypePrecommit { return fmt.Errorf("Invalid validation -- not precommit @ index %v", idx) } _, val := valSet.GetByIndex(idx) diff --git a/state/validator_set_test.go b/types/validator_set_test.go similarity index 99% rename from state/validator_set_test.go rename to types/validator_set_test.go index 998de41d..c8b5d307 100644 --- a/state/validator_set_test.go +++ b/types/validator_set_test.go @@ -1,4 +1,4 @@ -package state +package types import ( "github.com/tendermint/tendermint/account" diff --git a/consensus/vote_set.go b/types/vote_set.go similarity index 75% rename from consensus/vote_set.go rename to types/vote_set.go index 643cb32e..1b742b6c 100644 --- a/consensus/vote_set.go +++ b/types/vote_set.go @@ -1,4 +1,4 @@ -package consensus +package types import ( "bytes" @@ -7,10 +7,8 @@ import ( "sync" acm "github.com/tendermint/tendermint/account" - "github.com/tendermint/tendermint/wire" . "github.com/tendermint/tendermint/common" - sm "github.com/tendermint/tendermint/state" - "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/wire" ) // VoteSet helps collect signatures from validators at each height+round @@ -24,18 +22,18 @@ type VoteSet struct { type_ byte mtx sync.Mutex - valSet *sm.ValidatorSet - votes []*types.Vote // validator index -> vote + valSet *ValidatorSet + votes []*Vote // validator index -> vote votesBitArray *BitArray // validator index -> has vote? votesByBlock map[string]int64 // string(blockHash)+string(blockParts) -> vote sum. totalVotes int64 maj23Hash []byte - maj23Parts types.PartSetHeader + maj23Parts PartSetHeader maj23Exists bool } // Constructs a new VoteSet struct used to accumulate votes for given height/round. -func NewVoteSet(height int, round int, type_ byte, valSet *sm.ValidatorSet) *VoteSet { +func NewVoteSet(height int, round int, type_ byte, valSet *ValidatorSet) *VoteSet { if height == 0 { PanicSanity("Cannot make VoteSet for height == 0, doesn't make sense.") } @@ -44,7 +42,7 @@ func NewVoteSet(height int, round int, type_ byte, valSet *sm.ValidatorSet) *Vot round: round, type_: type_, valSet: valSet, - votes: make([]*types.Vote, valSet.Size()), + votes: make([]*Vote, valSet.Size()), votesBitArray: NewBitArray(valSet.Size()), votesByBlock: make(map[string]int64), totalVotes: 0, @@ -87,7 +85,7 @@ func (voteSet *VoteSet) Size() int { // Otherwise returns err=ErrVote[UnexpectedStep|InvalidAccount|InvalidSignature|InvalidBlockHash|ConflictingSignature] // Duplicate votes return added=false, err=nil. // NOTE: vote should not be mutated after adding. -func (voteSet *VoteSet) AddByIndex(valIndex int, vote *types.Vote) (added bool, index int, err error) { +func (voteSet *VoteSet) AddByIndex(valIndex int, vote *Vote) (added bool, index int, err error) { voteSet.mtx.Lock() defer voteSet.mtx.Unlock() @@ -98,42 +96,42 @@ func (voteSet *VoteSet) AddByIndex(valIndex int, vote *types.Vote) (added bool, // Otherwise returns err=ErrVote[UnexpectedStep|InvalidAccount|InvalidSignature|InvalidBlockHash|ConflictingSignature] // Duplicate votes return added=false, err=nil. // NOTE: vote should not be mutated after adding. -func (voteSet *VoteSet) AddByAddress(address []byte, vote *types.Vote) (added bool, index int, err error) { +func (voteSet *VoteSet) AddByAddress(address []byte, vote *Vote) (added bool, index int, err error) { voteSet.mtx.Lock() defer voteSet.mtx.Unlock() // Ensure that signer is a validator. valIndex, val := voteSet.valSet.GetByAddress(address) if val == nil { - return false, 0, types.ErrVoteInvalidAccount + return false, 0, ErrVoteInvalidAccount } return voteSet.addVote(val, valIndex, vote) } -func (voteSet *VoteSet) addByIndex(valIndex int, vote *types.Vote) (bool, int, error) { +func (voteSet *VoteSet) addByIndex(valIndex int, vote *Vote) (bool, int, error) { // Ensure that signer is a validator. _, val := voteSet.valSet.GetByIndex(valIndex) if val == nil { - return false, 0, types.ErrVoteInvalidAccount + return false, 0, ErrVoteInvalidAccount } return voteSet.addVote(val, valIndex, vote) } -func (voteSet *VoteSet) addVote(val *sm.Validator, valIndex int, vote *types.Vote) (bool, int, error) { +func (voteSet *VoteSet) addVote(val *Validator, valIndex int, vote *Vote) (bool, int, error) { // Make sure the step matches. (or that vote is commit && round < voteSet.round) if (vote.Height != voteSet.height) || (vote.Round != voteSet.round) || (vote.Type != voteSet.type_) { - return false, 0, types.ErrVoteUnexpectedStep + return false, 0, ErrVoteUnexpectedStep } // Check signature. if !val.PubKey.VerifyBytes(acm.SignBytes(config.GetString("chain_id"), vote), vote.Signature) { // Bad signature. - return false, 0, types.ErrVoteInvalidSignature + return false, 0, ErrVoteInvalidSignature } // If vote already exists, return false. @@ -141,7 +139,7 @@ func (voteSet *VoteSet) addVote(val *sm.Validator, valIndex int, vote *types.Vot if bytes.Equal(existingVote.BlockHash, vote.BlockHash) { return false, valIndex, nil } else { - return false, valIndex, &types.ErrVoteConflictingSignature{ + return false, valIndex, &ErrVoteConflictingSignature{ VoteA: existingVote, VoteB: vote, } @@ -176,13 +174,13 @@ func (voteSet *VoteSet) BitArray() *BitArray { return voteSet.votesBitArray.Copy() } -func (voteSet *VoteSet) GetByIndex(valIndex int) *types.Vote { +func (voteSet *VoteSet) GetByIndex(valIndex int) *Vote { voteSet.mtx.Lock() defer voteSet.mtx.Unlock() return voteSet.votes[valIndex] } -func (voteSet *VoteSet) GetByAddress(address []byte) *types.Vote { +func (voteSet *VoteSet) GetByAddress(address []byte) *Vote { voteSet.mtx.Lock() defer voteSet.mtx.Unlock() valIndex, val := voteSet.valSet.GetByAddress(address) @@ -221,13 +219,13 @@ func (voteSet *VoteSet) HasTwoThirdsAny() bool { // Returns either a blockhash (or nil) that received +2/3 majority. // If there exists no such majority, returns (nil, false). -func (voteSet *VoteSet) TwoThirdsMajority() (hash []byte, parts types.PartSetHeader, ok bool) { +func (voteSet *VoteSet) TwoThirdsMajority() (hash []byte, parts PartSetHeader, ok bool) { voteSet.mtx.Lock() defer voteSet.mtx.Unlock() if voteSet.maj23Exists { return voteSet.maj23Hash, voteSet.maj23Parts, true } else { - return nil, types.PartSetHeader{}, false + return nil, PartSetHeader{}, false } } @@ -271,17 +269,17 @@ func (voteSet *VoteSet) StringShort() string { //-------------------------------------------------------------------------------- // Validation -func (voteSet *VoteSet) MakeValidation() *types.Validation { - if voteSet.type_ != types.VoteTypePrecommit { - PanicSanity("Cannot MakeValidation() unless VoteSet.Type is types.VoteTypePrecommit") +func (voteSet *VoteSet) MakeValidation() *Validation { + if voteSet.type_ != VoteTypePrecommit { + PanicSanity("Cannot MakeValidation() unless VoteSet.Type is VoteTypePrecommit") } voteSet.mtx.Lock() defer voteSet.mtx.Unlock() if len(voteSet.maj23Hash) == 0 { PanicSanity("Cannot MakeValidation() unless a blockhash has +2/3") } - precommits := make([]*types.Vote, voteSet.valSet.Size()) - voteSet.valSet.Iterate(func(valIndex int, val *sm.Validator) bool { + precommits := make([]*Vote, voteSet.valSet.Size()) + voteSet.valSet.Iterate(func(valIndex int, val *Validator) bool { vote := voteSet.votes[valIndex] if vote == nil { return false @@ -295,7 +293,40 @@ func (voteSet *VoteSet) MakeValidation() *types.Validation { precommits[valIndex] = vote return false }) - return &types.Validation{ + return &Validation{ Precommits: precommits, } } + +//-------------------------------------------------------------------------------- +// For testing... + +func RandValidator(randBonded bool, minBonded int64) (*ValidatorInfo, *Validator, *PrivValidator) { + privVal := GenPrivValidator() + _, tempFilePath := Tempfile("priv_validator_") + privVal.SetFile(tempFilePath) + bonded := minBonded + if randBonded { + bonded += int64(RandUint32()) + } + valInfo := &ValidatorInfo{ + Address: privVal.Address, + PubKey: privVal.PubKey, + UnbondTo: []*TxOutput{&TxOutput{ + Amount: bonded, + Address: privVal.Address, + }}, + FirstBondHeight: 0, + FirstBondAmount: bonded, + } + val := &Validator{ + Address: valInfo.Address, + PubKey: valInfo.PubKey, + BondHeight: 0, + UnbondHeight: 0, + LastCommitHeight: 0, + VotingPower: valInfo.FirstBondAmount, + Accum: 0, + } + return valInfo, val, privVal +} diff --git a/consensus/vote_set_test.go b/types/vote_set_test.go similarity index 74% rename from consensus/vote_set_test.go rename to types/vote_set_test.go index d6daab19..1f7d4025 100644 --- a/consensus/vote_set_test.go +++ b/types/vote_set_test.go @@ -1,55 +1,65 @@ -package consensus +package types import ( "bytes" + "sort" . "github.com/tendermint/tendermint/common" . "github.com/tendermint/tendermint/common/test" _ "github.com/tendermint/tendermint/config/tendermint_test" - sm "github.com/tendermint/tendermint/state" - "github.com/tendermint/tendermint/types" "testing" ) -// NOTE: see consensus/test.go for common test methods. +func randVoteSet(height int, round int, type_ byte, numValidators int, votingPower int64) (*VoteSet, *ValidatorSet, []*PrivValidator) { + vals := make([]*Validator, numValidators) + privValidators := make([]*PrivValidator, numValidators) + for i := 0; i < numValidators; i++ { + _, val, privValidator := RandValidator(false, votingPower) + vals[i] = val + privValidators[i] = privValidator + } + valSet := NewValidatorSet(vals) + sort.Sort(PrivValidatorsByAddress(privValidators)) + return NewVoteSet(height, round, type_, valSet), valSet, privValidators +} // Convenience: Return new vote with different height -func withHeight(vote *types.Vote, height int) *types.Vote { +func withHeight(vote *Vote, height int) *Vote { vote = vote.Copy() vote.Height = height return vote } // Convenience: Return new vote with different round -func withRound(vote *types.Vote, round int) *types.Vote { +func withRound(vote *Vote, round int) *Vote { vote = vote.Copy() vote.Round = round return vote } // Convenience: Return new vote with different type -func withType(vote *types.Vote, type_ byte) *types.Vote { +func withType(vote *Vote, type_ byte) *Vote { vote = vote.Copy() vote.Type = type_ return vote } // Convenience: Return new vote with different blockHash -func withBlockHash(vote *types.Vote, blockHash []byte) *types.Vote { +func withBlockHash(vote *Vote, blockHash []byte) *Vote { vote = vote.Copy() vote.BlockHash = blockHash return vote } // Convenience: Return new vote with different blockParts -func withBlockParts(vote *types.Vote, blockParts types.PartSetHeader) *types.Vote { +func withBlockParts(vote *Vote, blockParts PartSetHeader) *Vote { vote = vote.Copy() vote.BlockParts = blockParts return vote } -func signAddVote(privVal *sm.PrivValidator, vote *types.Vote, voteSet *VoteSet) (bool, error) { +func signAddVote(privVal *PrivValidator, vote *Vote, voteSet *VoteSet) (bool, error) { privVal.SignVoteUnsafe(config.GetString("chain_id"), vote) added, _, err := voteSet.AddByAddress(privVal.Address, vote) return added, err @@ -57,7 +67,7 @@ func signAddVote(privVal *sm.PrivValidator, vote *types.Vote, voteSet *VoteSet) func TestAddVote(t *testing.T) { height, round := 1, 0 - voteSet, _, privValidators := randVoteSet(height, round, types.VoteTypePrevote, 10, 1) + voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) val0 := privValidators[0] // t.Logf(">> %v", voteSet) @@ -73,7 +83,7 @@ func TestAddVote(t *testing.T) { t.Errorf("There should be no 2/3 majority") } - vote := &types.Vote{Height: height, Round: round, Type: types.VoteTypePrevote, BlockHash: nil} + vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil} signAddVote(val0, vote, voteSet) if voteSet.GetByAddress(val0.Address) == nil { @@ -90,9 +100,9 @@ func TestAddVote(t *testing.T) { func Test2_3Majority(t *testing.T) { height, round := 1, 0 - voteSet, _, privValidators := randVoteSet(height, round, types.VoteTypePrevote, 10, 1) + voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) - vote := &types.Vote{Height: height, Round: round, Type: types.VoteTypePrevote, BlockHash: nil} + vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil} // 6 out of 10 voted for nil. for i := 0; i < 6; i++ { @@ -124,13 +134,13 @@ func Test2_3Majority(t *testing.T) { func Test2_3MajorityRedux(t *testing.T) { height, round := 1, 0 - voteSet, _, privValidators := randVoteSet(height, round, types.VoteTypePrevote, 100, 1) + voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 100, 1) blockHash := CRandBytes(32) blockPartsTotal := 123 - blockParts := types.PartSetHeader{blockPartsTotal, CRandBytes(32)} + blockParts := PartSetHeader{blockPartsTotal, CRandBytes(32)} - vote := &types.Vote{Height: height, Round: round, Type: types.VoteTypePrevote, BlockHash: blockHash, BlockParts: blockParts} + vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: blockHash, BlockParts: blockParts} // 66 out of 100 voted for nil. for i := 0; i < 66; i++ { @@ -152,7 +162,7 @@ func Test2_3MajorityRedux(t *testing.T) { // 68th validator voted for a different BlockParts PartSetHeader { - blockParts := types.PartSetHeader{blockPartsTotal, CRandBytes(32)} + blockParts := PartSetHeader{blockPartsTotal, CRandBytes(32)} signAddVote(privValidators[67], withBlockParts(vote, blockParts), voteSet) hash, header, ok = voteSet.TwoThirdsMajority() if hash != nil || !header.IsZero() || ok { @@ -162,7 +172,7 @@ func Test2_3MajorityRedux(t *testing.T) { // 69th validator voted for different BlockParts Total { - blockParts := types.PartSetHeader{blockPartsTotal + 1, blockParts.Hash} + blockParts := PartSetHeader{blockPartsTotal + 1, blockParts.Hash} signAddVote(privValidators[68], withBlockParts(vote, blockParts), voteSet) hash, header, ok = voteSet.TwoThirdsMajority() if hash != nil || !header.IsZero() || ok { @@ -191,10 +201,10 @@ func Test2_3MajorityRedux(t *testing.T) { func TestBadVotes(t *testing.T) { height, round := 1, 0 - voteSet, _, privValidators := randVoteSet(height, round, types.VoteTypePrevote, 10, 1) + voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1) // val0 votes for nil. - vote := &types.Vote{Height: height, Round: round, Type: types.VoteTypePrevote, BlockHash: nil} + vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil} added, err := signAddVote(privValidators[0], vote, voteSet) if !added || err != nil { t.Errorf("Expected VoteSet.Add to succeed") @@ -219,7 +229,7 @@ func TestBadVotes(t *testing.T) { } // val3 votes of another type. - added, err = signAddVote(privValidators[3], withType(vote, types.VoteTypePrecommit), voteSet) + added, err = signAddVote(privValidators[3], withType(vote, VoteTypePrecommit), voteSet) if added { t.Errorf("Expected VoteSet.Add to fail, wrong type") } @@ -227,10 +237,10 @@ func TestBadVotes(t *testing.T) { func TestMakeValidation(t *testing.T) { height, round := 1, 0 - voteSet, _, privValidators := randVoteSet(height, round, types.VoteTypePrecommit, 10, 1) - blockHash, blockParts := CRandBytes(32), types.PartSetHeader{123, CRandBytes(32)} + voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrecommit, 10, 1) + blockHash, blockParts := CRandBytes(32), PartSetHeader{123, CRandBytes(32)} - vote := &types.Vote{Height: height, Round: round, Type: types.VoteTypePrecommit, + vote := &Vote{Height: height, Round: round, Type: VoteTypePrecommit, BlockHash: blockHash, BlockParts: blockParts} // 6 out of 10 voted for some block. @@ -244,7 +254,7 @@ func TestMakeValidation(t *testing.T) { // 7th voted for some other block. { vote := withBlockHash(vote, RandBytes(32)) - vote = withBlockParts(vote, types.PartSetHeader{123, RandBytes(32)}) + vote = withBlockParts(vote, PartSetHeader{123, RandBytes(32)}) signAddVote(privValidators[6], vote, voteSet) } diff --git a/vm/test/fake_app_state.go b/vm/test/fake_app_state.go index 932cc497..f9661505 100644 --- a/vm/test/fake_app_state.go +++ b/vm/test/fake_app_state.go @@ -2,6 +2,7 @@ package vm import ( . "github.com/tendermint/tendermint/common" + "github.com/tendermint/tendermint/types" . "github.com/tendermint/tendermint/vm" "github.com/tendermint/tendermint/vm/sha3" ) @@ -9,7 +10,7 @@ import ( type FakeAppState struct { accounts map[string]*Account storage map[string]Word256 - logs []*Log + logs []types.EventDataLog } func (fas *FakeAppState) GetAccount(addr Word256) *Account { @@ -69,7 +70,7 @@ func (fas *FakeAppState) SetStorage(addr Word256, key Word256, value Word256) { fas.storage[addr.String()+key.String()] = value } -func (fas *FakeAppState) AddLog(log *Log) { +func (fas *FakeAppState) AddLog(log types.EventDataLog) { fas.logs = append(fas.logs, log) } diff --git a/vm/test/log_event_test.go b/vm/test/log_event_test.go index b2a81991..6107de52 100644 --- a/vm/test/log_event_test.go +++ b/vm/test/log_event_test.go @@ -45,7 +45,7 @@ func TestLog4(t *testing.T) { doneChan := make(chan struct{}, 1) eventSwitch.AddListenerForEvent("test", eventId, func(event interface{}) { - logEvent := event.(*Log) + logEvent := event.(types.EventDataLog) // No need to test address as this event would not happen if it wasn't correct if !reflect.DeepEqual(logEvent.Topics, expectedTopics) { t.Errorf("Event topics are wrong. Got: %v. Expected: %v", logEvent.Topics, expectedTopics) diff --git a/vm/test/vm_test.go b/vm/test/vm_test.go index a124bfb6..4ea33e3e 100644 --- a/vm/test/vm_test.go +++ b/vm/test/vm_test.go @@ -175,9 +175,9 @@ func runVMWaitEvents(t *testing.T, ourVm *VM, caller, callee *Account, subscribe }() msg := <-ch switch ev := msg.(type) { - case types.EventMsgTx: + case types.EventDataTx: return ev.Exception - case types.EventMsgCall: + case types.EventDataCall: return ev.Exception case string: return ev diff --git a/vm/types.go b/vm/types.go index a5fe34ef..74074a42 100644 --- a/vm/types.go +++ b/vm/types.go @@ -3,6 +3,7 @@ package vm import ( . "github.com/tendermint/tendermint/common" ptypes "github.com/tendermint/tendermint/permission/types" + "github.com/tendermint/tendermint/types" ) const ( @@ -27,15 +28,6 @@ func (acc *Account) String() string { acc.Address, acc.Balance, acc.Code, acc.Nonce) } -// NOTE: This is serialized as an event from vm/vm. -// See: EventStringLogEvent -type Log struct { - Address Word256 `json:"address"` - Topics []Word256 `json:"topics"` - Data []byte `json:"data"` - Height int64 `json:"height"` -} - type AppState interface { // Accounts @@ -49,7 +41,7 @@ type AppState interface { SetStorage(Word256, Word256, Word256) // Setting to Zero is deleting. // Logs - AddLog(*Log) + AddLog(types.EventDataLog) } type Params struct { diff --git a/vm/vm.go b/vm/vm.go index 8d252b33..40569275 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -98,7 +98,7 @@ func HasPermission(appState AppState, acc *Account, perm ptypes.PermFlag) bool { func (vm *VM) fireCallEvent(exception *string, output *[]byte, caller, callee *Account, input []byte, value int64, gas *int64) { // fire the post call event (including exception if applicable) if vm.evc != nil { - vm.evc.FireEvent(types.EventStringAccCall(callee.Address.Postfix(20)), types.EventMsgCall{ + vm.evc.FireEvent(types.EventStringAccCall(callee.Address.Postfix(20)), types.EventDataCall{ &types.CallData{caller.Address.Postfix(20), callee.Address.Postfix(20), input, value, *gas}, vm.origin.Postfix(20), vm.txid, @@ -694,7 +694,7 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value int64, gas if !ok { return nil, firstErr(err, ErrMemoryOutOfBounds) } - log := &Log{ + log := types.EventDataLog{ callee.Address, topics, data, diff --git a/wire/reflect.go b/wire/reflect.go index 03c9deb2..c7745a4e 100644 --- a/wire/reflect.go +++ b/wire/reflect.go @@ -585,6 +585,7 @@ func readByteJSON(o interface{}) (typeByte byte, rest interface{}, err error) { // Contract: Caller must ensure that rt is supported // (e.g. is recursively composed of supported native types, and structs and slices.) +// rv and rt refer to the object we're unmarhsaling into, whereas o is the result of naiive json unmarshal (map[string]interface{}) func readReflectJSON(rv reflect.Value, rt reflect.Type, o interface{}, err *error) { // Get typeInfo diff --git a/wire/wire.go b/wire/wire.go index 3dc9cabb..aece054f 100644 --- a/wire/wire.go +++ b/wire/wire.go @@ -71,6 +71,7 @@ func ReadJSONPtr(o interface{}, bytes []byte, err *error) interface{} { return ReadJSONObjectPtr(o, object, err) } +// o is the ultimate destination, object is the result of json unmarshal func ReadJSONObject(o interface{}, object interface{}, err *error) interface{} { rv, rt := reflect.ValueOf(o), reflect.TypeOf(o) if rv.Kind() == reflect.Ptr {