diff --git a/rpc/core/blocks.go b/rpc/core/blocks.go index 115ca2a9c..f1e47d416 100644 --- a/rpc/core/blocks.go +++ b/rpc/core/blocks.go @@ -44,3 +44,26 @@ func Block(height int) (*ctypes.ResultBlock, error) { block := blockStore.LoadBlock(height) return &ctypes.ResultBlock{blockMeta, block}, nil } + +//----------------------------------------------------------------------------- + +func Commit(height int) (*ctypes.ResultCommit, error) { + if height == 0 { + return nil, fmt.Errorf("Height must be greater than 0") + } + storeHeight := blockStore.Height() + if height > storeHeight { + return nil, fmt.Errorf("Height must be less than or equal to the current blockchain height") + } + + // If the next block has not been committed yet, + // use a non-canonical commit + if height == storeHeight+1 { + commit := blockStore.LoadSeenCommit(height) + return &ctypes.ResultCommit{commit, false}, nil + } + + // Return the canonical commit (comes from the block at height+1) + commit := blockStore.LoadBlockCommit(height) + return &ctypes.ResultCommit{commit, true}, nil +} diff --git a/rpc/core/pipe.go b/rpc/core/pipe.go index 356a2ff0d..16bd8f20f 100644 --- a/rpc/core/pipe.go +++ b/rpc/core/pipe.go @@ -5,10 +5,10 @@ import ( "github.com/tendermint/go-crypto" "github.com/tendermint/go-p2p" + abci "github.com/tendermint/abci/types" "github.com/tendermint/tendermint/consensus" "github.com/tendermint/tendermint/proxy" "github.com/tendermint/tendermint/types" - abci "github.com/tendermint/abci/types" ) //----------------------------------------------------- @@ -19,6 +19,8 @@ type BlockStore interface { Height() int LoadBlockMeta(height int) *types.BlockMeta LoadBlock(height int) *types.Block + LoadSeenCommit(height int) *types.Commit + LoadBlockCommit(height int) *types.Commit } type Consensus interface { diff --git a/rpc/core/routes.go b/rpc/core/routes.go index 8396cd23c..643b2bf02 100644 --- a/rpc/core/routes.go +++ b/rpc/core/routes.go @@ -18,6 +18,7 @@ var Routes = map[string]*rpc.RPCFunc{ "blockchain": rpc.NewRPCFunc(BlockchainInfoResult, "minHeight,maxHeight"), "genesis": rpc.NewRPCFunc(GenesisResult, ""), "block": rpc.NewRPCFunc(BlockResult, "height"), + "commit": rpc.NewRPCFunc(CommitResult, "height"), "validators": rpc.NewRPCFunc(ValidatorsResult, ""), "dump_consensus_state": rpc.NewRPCFunc(DumpConsensusStateResult, ""), "unconfirmed_txs": rpc.NewRPCFunc(UnconfirmedTxsResult, ""), @@ -107,6 +108,14 @@ func BlockResult(height int) (ctypes.TMResult, error) { } } +func CommitResult(height int) (ctypes.TMResult, error) { + if r, err := Commit(height); err != nil { + return nil, err + } else { + return r, nil + } +} + func ValidatorsResult() (ctypes.TMResult, error) { if r, err := Validators(); err != nil { return nil, err diff --git a/rpc/core/types/responses.go b/rpc/core/types/responses.go index 1a5deaeab..b68f169a4 100644 --- a/rpc/core/types/responses.go +++ b/rpc/core/types/responses.go @@ -23,6 +23,11 @@ type ResultBlock struct { Block *types.Block `json:"block"` } +type ResultCommit struct { + Commit *types.Commit `json:"commit"` + Canonical bool `json:"canonical"` +} + type ResultStatus struct { NodeInfo *p2p.NodeInfo `json:"node_info"` PubKey crypto.PubKey `json:"pub_key"` @@ -106,6 +111,7 @@ const ( ResultTypeGenesis = byte(0x01) ResultTypeBlockchainInfo = byte(0x02) ResultTypeBlock = byte(0x03) + ResultTypeCommit = byte(0x04) // 0x2 bytes are for the network ResultTypeStatus = byte(0x20) @@ -148,6 +154,7 @@ var _ = wire.RegisterInterface( wire.ConcreteType{&ResultGenesis{}, ResultTypeGenesis}, wire.ConcreteType{&ResultBlockchainInfo{}, ResultTypeBlockchainInfo}, wire.ConcreteType{&ResultBlock{}, ResultTypeBlock}, + wire.ConcreteType{&ResultCommit{}, ResultTypeCommit}, wire.ConcreteType{&ResultStatus{}, ResultTypeStatus}, wire.ConcreteType{&ResultNetInfo{}, ResultTypeNetInfo}, wire.ConcreteType{&ResultDialSeeds{}, ResultTypeDialSeeds},