Merge pull request #405 from tendermint/rpc-commit

Rpc commit
This commit is contained in:
Ethan Buchman 2017-02-16 16:11:39 -05:00 committed by GitHub
commit 3ebd69db1b
16 changed files with 90 additions and 59 deletions

View File

@ -22,7 +22,7 @@ dist:
test:
@echo "--> Running go test"
@go test -v $(PACKAGES)
@go test $(PACKAGES)
test_race:
@echo "--> Running go test --race"

View File

@ -64,12 +64,12 @@ func (bs *BlockStore) LoadBlock(height int) *types.Block {
if r == nil {
return nil
}
meta := wire.ReadBinary(&types.BlockMeta{}, r, 0, &n, &err).(*types.BlockMeta)
blockMeta := wire.ReadBinary(&types.BlockMeta{}, r, 0, &n, &err).(*types.BlockMeta)
if err != nil {
PanicCrisis(Fmt("Error reading block meta: %v", err))
}
bytez := []byte{}
for i := 0; i < meta.PartsHeader.Total; i++ {
for i := 0; i < blockMeta.BlockID.PartsHeader.Total; i++ {
part := bs.LoadBlockPart(height, i)
bytez = append(bytez, part.Bytes...)
}
@ -101,11 +101,11 @@ func (bs *BlockStore) LoadBlockMeta(height int) *types.BlockMeta {
if r == nil {
return nil
}
meta := wire.ReadBinary(&types.BlockMeta{}, r, 0, &n, &err).(*types.BlockMeta)
blockMeta := wire.ReadBinary(&types.BlockMeta{}, r, 0, &n, &err).(*types.BlockMeta)
if err != nil {
PanicCrisis(Fmt("Error reading block meta: %v", err))
}
return meta
return blockMeta
}
// The +2/3 and other Precommit-votes for block at `height`.
@ -154,8 +154,8 @@ func (bs *BlockStore) SaveBlock(block *types.Block, blockParts *types.PartSet, s
}
// Save block meta
meta := types.NewBlockMeta(block, blockParts)
metaBytes := wire.BinaryBytes(meta)
blockMeta := types.NewBlockMeta(block, blockParts)
metaBytes := wire.BinaryBytes(blockMeta)
bs.db.Set(calcBlockMetaKey(height), metaBytes)
// Save block parts

View File

@ -114,6 +114,8 @@ func TestRmBadTx(t *testing.T) {
// CounterApplication that maintains a mempool state and resets it upon commit
type CounterApplication struct {
abci.BaseApplication
txCount int
mempoolTxCount int
}
@ -126,10 +128,6 @@ func (app *CounterApplication) Info() abci.ResponseInfo {
return abci.ResponseInfo{Data: Fmt("txs:%v", app.txCount)}
}
func (app *CounterApplication) SetOption(key string, value string) (log string) {
return ""
}
func (app *CounterApplication) DeliverTx(tx []byte) abci.Result {
return runTx(tx, &app.txCount)
}
@ -160,8 +158,3 @@ func (app *CounterApplication) Commit() abci.Result {
return abci.NewResultOK(hash, "")
}
}
func (app *CounterApplication) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQuery) {
resQuery.Log = "Query is not supported"
return
}

View File

@ -415,9 +415,9 @@ OUTER_LOOP:
log.Warn("Failed to load block meta", "peer height", prs.Height, "our height", rs.Height, "blockstore height", conR.conS.blockStore.Height(), "pv", conR.conS.privValidator)
time.Sleep(peerGossipSleepDuration)
continue OUTER_LOOP
} else if !blockMeta.PartsHeader.Equals(prs.ProposalBlockPartsHeader) {
} else if !blockMeta.BlockID.PartsHeader.Equals(prs.ProposalBlockPartsHeader) {
log.Info("Peer ProposalBlockPartsHeader mismatch, sleeping",
"peerHeight", prs.Height, "blockPartsHeader", blockMeta.PartsHeader, "peerBlockPartsHeader", prs.ProposalBlockPartsHeader)
"peerHeight", prs.Height, "blockPartsHeader", blockMeta.BlockID.PartsHeader, "peerBlockPartsHeader", prs.ProposalBlockPartsHeader)
time.Sleep(peerGossipSleepDuration)
continue OUTER_LOOP
}
@ -425,7 +425,7 @@ OUTER_LOOP:
part := conR.conS.blockStore.LoadBlockPart(prs.Height, index)
if part == nil {
log.Warn("Could not load part", "index", index,
"peerHeight", prs.Height, "blockPartsHeader", blockMeta.PartsHeader, "peerBlockPartsHeader", prs.ProposalBlockPartsHeader)
"peerHeight", prs.Height, "blockPartsHeader", blockMeta.BlockID.PartsHeader, "peerBlockPartsHeader", prs.ProposalBlockPartsHeader)
time.Sleep(peerGossipSleepDuration)
continue OUTER_LOOP
}

View File

@ -2,7 +2,7 @@
ABCI is an interface between the consensus/blockchain engine known as tendermint, and the application-specific business logic, known as an ABCi app.
The tendermint core should run unchanged for all apps. Each app can customize it, the supported transactions, queries, even the validator sets and hwo to handle staking / slashing stake. This customization is achieved by implementing the ABCi app to send the proper information to the tendermint engine to perform as directed.
The tendermint core should run unchanged for all apps. Each app can customize it, the supported transactions, queries, even the validator sets and how to handle staking / slashing stake. This customization is achieved by implementing the ABCi app to send the proper information to the tendermint engine to perform as directed.
To understand this decision better, think of the design of the tendermint engine.

View File

@ -11,7 +11,7 @@ What are some of the requirements of this store:
* We must only persist complete blocks, so when we come up after a crash we are at the state of block N or N+1, but not in-between these two states.
* It must allow us to read/write from one uncommited state (working state), while serving other queries from the last commited state. And a way to determine which one to serve for each client.
* It must allow us to hold references to old state, to allow providing proofs from 20 blocks ago. We can define some limits as to the maximum time to hold this data.
* We provide in process binding in the go-lanaguage
* We provide in process binding in Go
* We provide language-agnostic bindings when running the data store as it's own process.

40
glide.lock generated
View File

@ -1,12 +1,10 @@
hash: e283934fbbd221161d53a918db9e49db8c5be2b8929592b05ffe6b72c2ef0ab1
updated: 2017-01-27T22:32:42.896956819-08:00
updated: 2017-02-14T17:07:40.028389369-05:00
imports:
- name: github.com/btcsuite/btcd
version: afec1bd1245a4a19e6dfe1306974b733e7cbb9b8
version: d06c0bb181529331be8f8d9350288c420d9e60e4
subpackages:
- btcec
- name: github.com/btcsuite/fastsha256
version: 637e656429416087660c84436a2a035d69d54e2e
- name: github.com/BurntSushi/toml
version: 99064174e013895bbd9b025c31100bd1d9b590ca
- name: github.com/ebuchman/fail-test
@ -14,27 +12,27 @@ imports:
- name: github.com/go-stack/stack
version: 100eb0c0a9c5b306ca2fb4f165df21d80ada4b82
- name: github.com/gogo/protobuf
version: f9114dace7bd920b32f943b3c73fafbcbab2bf31
version: 2221ff550f109ae54cb617c0dc6ac62658c418d7
subpackages:
- proto
- name: github.com/golang/protobuf
version: 1f49d83d9aa00e6ce4fc8258c71cc7786aec968a
version: 8ee79997227bf9b34611aee7946ae64735e6fd93
subpackages:
- proto
- name: github.com/golang/snappy
version: d9eb7a3d35ec988b8585d4a0068e462c27d28380
version: 7db9049039a047d955fe8c19b83c8ff5abd765c7
- name: github.com/gorilla/websocket
version: 3ab3a8b8831546bd18fd182c20687ca853b2bb13
version: 804cb600d06b10672f2fbc0a336a7bee507a428e
- name: github.com/jmhodges/levigo
version: c42d9e0ca023e2198120196f842701bb4c55d7b9
- name: github.com/mattn/go-colorable
version: ed8eb9e318d7a84ce5915b495b7d35e0cfe7b5a8
version: 5411d3eea5978e6cdc258b30de592b60df6aba96
- name: github.com/mattn/go-isatty
version: 66b8e73f3f5cda9f96b69efd03dd3d7fc4a5cdb8
version: 281032e84ae07510239465db46bf442aa44b953a
- name: github.com/spf13/pflag
version: 5ccb023bc27df288a957c5e994cd44fd19619465
version: 9ff6c6923cfffbcd502984b8e0c80539a94968b7
- name: github.com/syndtr/goleveldb
version: 6ae1797c0b42b9323fc27ff7dcf568df88f2f33d
version: 23851d93a2292dcc56e71a18ec9e0624d84a0f65
subpackages:
- leveldb
- leveldb/cache
@ -49,12 +47,11 @@ imports:
- leveldb/table
- leveldb/util
- name: github.com/tendermint/abci
version: 8df0bc3a40ccad0d2be10e33c62c404e65c92502
version: 31bdda27ad80e47d372e4b9e4acfd4c0ef81d3e4
subpackages:
- client
- example/counter
- example/dummy
- example/nil
- server
- types
- name: github.com/tendermint/ed25519
@ -85,7 +82,7 @@ imports:
- name: github.com/tendermint/go-logger
version: cefb3a45c0bf3c493a04e9bcd9b1540528be59f2
- name: github.com/tendermint/go-merkle
version: 653cb1f631528351ddbc359b994eb0c96f0341cd
version: 9f20e80cb188d07860caa70196dd7700659ec4a4
- name: github.com/tendermint/go-p2p
version: 67c9086b7458eb45b1970483decd01cd744c477a
subpackages:
@ -97,13 +94,13 @@ imports:
- server
- types
- name: github.com/tendermint/go-wire
version: 2f3b7aafe21c80b19b6ee3210ecb3e3d07c7a471
version: 3216ec9d47bbdf8d4fc27d22169ea86a6688bc15
- name: github.com/tendermint/log15
version: 9545b249b3aacafa97f79e0838b02b274adc6f5f
version: ae0f3d6450da9eac7074b439c8e1c3cabf0d5ce6
subpackages:
- term
- name: golang.org/x/crypto
version: aa2481cbfe81d911eb62b642b7a6b5ec58bbea71
version: 453249f01cfeb54c3d549ddb75ff152ca243f9d8
subpackages:
- curve25519
- nacl/box
@ -114,20 +111,21 @@ imports:
- ripemd160
- salsa20/salsa
- name: golang.org/x/net
version: cfe3c2a7525b50c3d707256e371c90938cfef98a
version: 61557ac0112b576429a0df080e1c2cef5dfbb642
subpackages:
- context
- http2
- http2/hpack
- idna
- internal/timeseries
- lex/httplex
- trace
- name: golang.org/x/sys
version: 30de6d19a3bd89a5f38ae4028e23aaa5582648af
version: e24f485414aeafb646f6fca458b0bf869c0880a1
subpackages:
- unix
- name: google.golang.org/grpc
version: 50955793b0183f9de69bd78e2ec251cf20aab121
version: cbcceb2942a489498cf22b2f918536e819d33f0a
subpackages:
- codes
- credentials

View File

@ -4,11 +4,10 @@ import (
"fmt"
"sync"
cfg "github.com/tendermint/go-config"
abcicli "github.com/tendermint/abci/client"
"github.com/tendermint/abci/example/dummy"
nilapp "github.com/tendermint/abci/example/nil"
"github.com/tendermint/abci/types"
cfg "github.com/tendermint/go-config"
)
// NewABCIClient returns newly connected client
@ -74,7 +73,7 @@ func DefaultClientCreator(config cfg.Config) ClientCreator {
case "persistent_dummy":
return NewLocalClientCreator(dummy.NewPersistentDummyApplication(config.GetString("db_dir")))
case "nilapp":
return NewLocalClientCreator(nilapp.NewNilApplication())
return NewLocalClientCreator(types.NewBaseApplication())
default:
mustConnect := false // loop retrying
return NewRemoteClientCreator(addr, transport, mustConnect)

View File

@ -44,3 +44,28 @@ 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")
}
header := blockStore.LoadBlockMeta(height).Header
// If the next block has not been committed yet,
// use a non-canonical commit
if height == storeHeight {
commit := blockStore.LoadSeenCommit(height)
return &ctypes.ResultCommit{header, commit, false}, nil
}
// Return the canonical commit (comes from the block at height+1)
commit := blockStore.LoadBlockCommit(height)
return &ctypes.ResultCommit{header, commit, true}, nil
}

View File

@ -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 {

View File

@ -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

View File

@ -15,7 +15,7 @@ func Status() (*ctypes.ResultStatus, error) {
)
if latestHeight != 0 {
latestBlockMeta = blockStore.LoadBlockMeta(latestHeight)
latestBlockHash = latestBlockMeta.Hash
latestBlockHash = latestBlockMeta.BlockID.Hash
latestAppHash = latestBlockMeta.Header.AppHash
latestBlockTime = latestBlockMeta.Header.Time.UnixNano()
}

View File

@ -23,6 +23,12 @@ type ResultBlock struct {
Block *types.Block `json:"block"`
}
type ResultCommit struct {
Header *types.Header `json:"header"`
Commit *types.Commit `json:"commit"`
CanonicalCommit bool `json:"canonical"`
}
type ResultStatus struct {
NodeInfo *p2p.NodeInfo `json:"node_info"`
PubKey crypto.PubKey `json:"pub_key"`
@ -106,6 +112,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 +155,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},

View File

@ -6,12 +6,12 @@ import (
"github.com/ebuchman/fail-test"
abci "github.com/tendermint/abci/types"
. "github.com/tendermint/go-common"
cfg "github.com/tendermint/go-config"
"github.com/tendermint/go-crypto"
"github.com/tendermint/tendermint/proxy"
"github.com/tendermint/tendermint/types"
abci "github.com/tendermint/abci/types"
)
//--------------------------------------------------
@ -393,7 +393,7 @@ func (h *Handshaker) ReplayBlocks(appHash []byte, appBlockHeight int, appConnCon
var eventCache types.Fireable // nil
// replay the latest block
return h.state.ApplyBlock(eventCache, appConnConsensus, block, blockMeta.PartsHeader, MockMempool{})
return h.state.ApplyBlock(eventCache, appConnConsensus, block, blockMeta.BlockID.PartsHeader, MockMempool{})
} else if storeBlockHeight != stateBlockHeight {
// unless we failed before committing or saving state (previous 2 case),
// the store and state should be at the same height!

View File

@ -8,12 +8,12 @@ import (
"github.com/tendermint/tendermint/config/tendermint_test"
// . "github.com/tendermint/go-common"
"github.com/tendermint/abci/example/dummy"
cfg "github.com/tendermint/go-config"
"github.com/tendermint/go-crypto"
dbm "github.com/tendermint/go-db"
"github.com/tendermint/tendermint/proxy"
"github.com/tendermint/tendermint/types"
"github.com/tendermint/abci/example/dummy"
)
var (
@ -203,8 +203,7 @@ func (bs *mockBlockStore) LoadBlock(height int) *types.Block { return bs.chain[h
func (bs *mockBlockStore) LoadBlockMeta(height int) *types.BlockMeta {
block := bs.chain[height-1]
return &types.BlockMeta{
Hash: block.Hash(),
Header: block.Header,
PartsHeader: block.MakePartSet(bs.config.GetInt("block_part_size")).Header(),
BlockID: types.BlockID{block.Hash(), block.MakePartSet(bs.config.GetInt("block_part_size")).Header()},
Header: block.Header,
}
}

View File

@ -1,15 +1,13 @@
package types
type BlockMeta struct {
Hash []byte `json:"hash"` // The block hash
Header *Header `json:"header"` // The block's Header
PartsHeader PartSetHeader `json:"parts_header"` // The PartSetHeader, for transfer
BlockID BlockID `json:"block_id"` // the block hash and partsethash
Header *Header `json:"header"` // The block's Header
}
func NewBlockMeta(block *Block, blockParts *PartSet) *BlockMeta {
return &BlockMeta{
Hash: block.Hash(),
Header: block.Header,
PartsHeader: blockParts.Header(),
BlockID: BlockID{block.Hash(), blockParts.Header()},
Header: block.Header,
}
}