Merge pull request #108 from tendermint/app-interface-upgrade

use request structs for InitChain and BeginBlock
This commit is contained in:
Ethan Buchman 2017-09-22 00:18:52 -04:00 committed by GitHub
commit 34e70090e6
13 changed files with 61 additions and 59 deletions

View File

@ -20,7 +20,7 @@ type Client interface {
SetOptionAsync(key string, value string) *ReqRes SetOptionAsync(key string, value string) *ReqRes
DeliverTxAsync(tx []byte) *ReqRes DeliverTxAsync(tx []byte) *ReqRes
CheckTxAsync(tx []byte) *ReqRes CheckTxAsync(tx []byte) *ReqRes
QueryAsync(reqQuery types.RequestQuery) *ReqRes QueryAsync(types.RequestQuery) *ReqRes
CommitAsync() *ReqRes CommitAsync() *ReqRes
FlushSync() error FlushSync() error
@ -29,15 +29,15 @@ type Client interface {
SetOptionSync(key string, value string) (res types.Result) SetOptionSync(key string, value string) (res types.Result)
DeliverTxSync(tx []byte) (res types.Result) DeliverTxSync(tx []byte) (res types.Result)
CheckTxSync(tx []byte) (res types.Result) CheckTxSync(tx []byte) (res types.Result)
QuerySync(reqQuery types.RequestQuery) (resQuery types.ResponseQuery, err error) QuerySync(types.RequestQuery) (resQuery types.ResponseQuery, err error)
CommitSync() (res types.Result) CommitSync() (res types.Result)
InitChainAsync(validators []*types.Validator) *ReqRes InitChainAsync(types.RequestInitChain) *ReqRes
BeginBlockAsync(hash []byte, header *types.Header) *ReqRes BeginBlockAsync(types.RequestBeginBlock) *ReqRes
EndBlockAsync(height uint64) *ReqRes EndBlockAsync(height uint64) *ReqRes
InitChainSync(validators []*types.Validator) (err error) InitChainSync(types.RequestInitChain) (err error)
BeginBlockSync(hash []byte, header *types.Header) (err error) BeginBlockSync(types.RequestBeginBlock) (err error)
EndBlockSync(height uint64) (resEndBlock types.ResponseEndBlock, err error) EndBlockSync(height uint64) (resEndBlock types.ResponseEndBlock, err error)
} }

View File

@ -190,8 +190,8 @@ func (cli *grpcClient) CommitAsync() *ReqRes {
return cli.finishAsyncCall(req, &types.Response{&types.Response_Commit{res}}) return cli.finishAsyncCall(req, &types.Response{&types.Response_Commit{res}})
} }
func (cli *grpcClient) InitChainAsync(validators []*types.Validator) *ReqRes { func (cli *grpcClient) InitChainAsync(params types.RequestInitChain) *ReqRes {
req := types.ToRequestInitChain(validators) req := types.ToRequestInitChain(params)
res, err := cli.client.InitChain(context.Background(), req.GetInitChain(), grpc.FailFast(true)) res, err := cli.client.InitChain(context.Background(), req.GetInitChain(), grpc.FailFast(true))
if err != nil { if err != nil {
cli.StopForError(err) cli.StopForError(err)
@ -199,8 +199,8 @@ func (cli *grpcClient) InitChainAsync(validators []*types.Validator) *ReqRes {
return cli.finishAsyncCall(req, &types.Response{&types.Response_InitChain{res}}) return cli.finishAsyncCall(req, &types.Response{&types.Response_InitChain{res}})
} }
func (cli *grpcClient) BeginBlockAsync(hash []byte, header *types.Header) *ReqRes { func (cli *grpcClient) BeginBlockAsync(params types.RequestBeginBlock) *ReqRes {
req := types.ToRequestBeginBlock(hash, header) req := types.ToRequestBeginBlock(params)
res, err := cli.client.BeginBlock(context.Background(), req.GetBeginBlock(), grpc.FailFast(true)) res, err := cli.client.BeginBlock(context.Background(), req.GetBeginBlock(), grpc.FailFast(true))
if err != nil { if err != nil {
cli.StopForError(err) cli.StopForError(err)
@ -319,13 +319,13 @@ func (cli *grpcClient) CommitSync() (res types.Result) {
return types.Result{Code: resp.Code, Data: resp.Data, Log: resp.Log} return types.Result{Code: resp.Code, Data: resp.Data, Log: resp.Log}
} }
func (cli *grpcClient) InitChainSync(validators []*types.Validator) (err error) { func (cli *grpcClient) InitChainSync(params types.RequestInitChain) (err error) {
cli.InitChainAsync(validators) cli.InitChainAsync(params)
return cli.Error() return cli.Error()
} }
func (cli *grpcClient) BeginBlockSync(hash []byte, header *types.Header) (err error) { func (cli *grpcClient) BeginBlockSync(params types.RequestBeginBlock) (err error) {
cli.BeginBlockAsync(hash, header) cli.BeginBlockAsync(params)
return cli.Error() return cli.Error()
} }

View File

@ -109,23 +109,23 @@ func (app *localClient) CommitAsync() *ReqRes {
) )
} }
func (app *localClient) InitChainAsync(validators []*types.Validator) *ReqRes { func (app *localClient) InitChainAsync(params types.RequestInitChain) *ReqRes {
app.mtx.Lock() app.mtx.Lock()
app.Application.InitChain(validators) app.Application.InitChain(params)
reqRes := app.callback( reqRes := app.callback(
types.ToRequestInitChain(validators), types.ToRequestInitChain(params),
types.ToResponseInitChain(), types.ToResponseInitChain(),
) )
app.mtx.Unlock() app.mtx.Unlock()
return reqRes return reqRes
} }
func (app *localClient) BeginBlockAsync(hash []byte, header *types.Header) *ReqRes { func (app *localClient) BeginBlockAsync(params types.RequestBeginBlock) *ReqRes {
app.mtx.Lock() app.mtx.Lock()
app.Application.BeginBlock(hash, header) app.Application.BeginBlock(params)
app.mtx.Unlock() app.mtx.Unlock()
return app.callback( return app.callback(
types.ToRequestBeginBlock(hash, header), types.ToRequestBeginBlock(params),
types.ToResponseBeginBlock(), types.ToResponseBeginBlock(),
) )
} }
@ -192,16 +192,16 @@ func (app *localClient) CommitSync() (res types.Result) {
return res return res
} }
func (app *localClient) InitChainSync(validators []*types.Validator) (err error) { func (app *localClient) InitChainSync(params types.RequestInitChain) (err error) {
app.mtx.Lock() app.mtx.Lock()
app.Application.InitChain(validators) app.Application.InitChain(params)
app.mtx.Unlock() app.mtx.Unlock()
return nil return nil
} }
func (app *localClient) BeginBlockSync(hash []byte, header *types.Header) (err error) { func (app *localClient) BeginBlockSync(params types.RequestBeginBlock) (err error) {
app.mtx.Lock() app.mtx.Lock()
app.Application.BeginBlock(hash, header) app.Application.BeginBlock(params)
app.mtx.Unlock() app.mtx.Unlock()
return nil return nil
} }

View File

@ -255,12 +255,12 @@ func (cli *socketClient) CommitAsync() *ReqRes {
return cli.queueRequest(types.ToRequestCommit()) return cli.queueRequest(types.ToRequestCommit())
} }
func (cli *socketClient) InitChainAsync(validators []*types.Validator) *ReqRes { func (cli *socketClient) InitChainAsync(params types.RequestInitChain) *ReqRes {
return cli.queueRequest(types.ToRequestInitChain(validators)) return cli.queueRequest(types.ToRequestInitChain(params))
} }
func (cli *socketClient) BeginBlockAsync(hash []byte, header *types.Header) *ReqRes { func (cli *socketClient) BeginBlockAsync(params types.RequestBeginBlock) *ReqRes {
return cli.queueRequest(types.ToRequestBeginBlock(hash, header)) return cli.queueRequest(types.ToRequestBeginBlock(params))
} }
func (cli *socketClient) EndBlockAsync(height uint64) *ReqRes { func (cli *socketClient) EndBlockAsync(height uint64) *ReqRes {
@ -352,8 +352,8 @@ func (cli *socketClient) CommitSync() (res types.Result) {
return types.Result{Code: resp.Code, Data: resp.Data, Log: resp.Log} return types.Result{Code: resp.Code, Data: resp.Data, Log: resp.Log}
} }
func (cli *socketClient) InitChainSync(validators []*types.Validator) (err error) { func (cli *socketClient) InitChainSync(params types.RequestInitChain) (err error) {
cli.queueRequest(types.ToRequestInitChain(validators)) cli.queueRequest(types.ToRequestInitChain(params))
cli.FlushSync() cli.FlushSync()
if err := cli.Error(); err != nil { if err := cli.Error(); err != nil {
return err return err
@ -361,8 +361,8 @@ func (cli *socketClient) InitChainSync(validators []*types.Validator) (err error
return nil return nil
} }
func (cli *socketClient) BeginBlockSync(hash []byte, header *types.Header) (err error) { func (cli *socketClient) BeginBlockSync(params types.RequestBeginBlock) (err error) {
cli.queueRequest(types.ToRequestBeginBlock(hash, header)) cli.queueRequest(types.ToRequestBeginBlock(params))
cli.FlushSync() cli.FlushSync()
if err := cli.Error(); err != nil { if err := cli.Error(); err != nil {
return err return err

View File

@ -55,7 +55,7 @@ func (app *ChainAwareApplication) Query(reqQuery types.RequestQuery) (resQuery t
} }
} }
func (app *ChainAwareApplication) BeginBlock(hash []byte, header *types.Header) { func (app *ChainAwareApplication) BeginBlock(reqBeginBlock types.RequestBeginBlock) {
app.beginCount++ app.beginCount++
return return
} }

View File

@ -37,7 +37,7 @@ func TestChainAware(t *testing.T) {
hash := []byte("fake block hash") hash := []byte("fake block hash")
header := &types.Header{} header := &types.Header{}
for i := uint64(0); i < n; i++ { for i := uint64(0); i < n; i++ {
client.BeginBlockSync(hash, header) client.BeginBlockSync(types.RequestBeginBlock{hash, header})
client.EndBlockSync(i) client.EndBlockSync(i)
client.CommitSync() client.CommitSync()
} }

View File

@ -91,7 +91,7 @@ func TestPersistentDummyInfo(t *testing.T) {
header := &types.Header{ header := &types.Header{
Height: uint64(height), Height: uint64(height),
} }
dummy.BeginBlock(hash, header) dummy.BeginBlock(types.RequestBeginBlock{hash, header})
dummy.EndBlock(height) dummy.EndBlock(height)
dummy.Commit() dummy.Commit()
@ -120,7 +120,7 @@ func TestValSetChanges(t *testing.T) {
vals[i] = &types.Validator{pubkey, uint64(power)} vals[i] = &types.Validator{pubkey, uint64(power)}
} }
// iniitalize with the first nInit // iniitalize with the first nInit
dummy.InitChain(vals[:nInit]) dummy.InitChain(types.RequestInitChain{vals[:nInit]})
vals1, vals2 := vals[:nInit], dummy.Validators() vals1, vals2 := vals[:nInit], dummy.Validators()
valsEqual(t, vals1, vals2) valsEqual(t, vals1, vals2)
@ -180,7 +180,7 @@ func makeApplyBlock(t *testing.T, dummy types.Application, heightInt int, diff [
Height: height, Height: height,
} }
dummy.BeginBlock(hash, header) dummy.BeginBlock(types.RequestBeginBlock{hash, header})
for _, tx := range txs { for _, tx := range txs {
if r := dummy.DeliverTx(tx); r.IsErr() { if r := dummy.DeliverTx(tx); r.IsErr() {
t.Fatal(r) t.Fatal(r)

View File

@ -106,8 +106,8 @@ func (app *PersistentDummyApplication) Query(reqQuery types.RequestQuery) types.
} }
// Save the validators in the merkle tree // Save the validators in the merkle tree
func (app *PersistentDummyApplication) InitChain(validators []*types.Validator) { func (app *PersistentDummyApplication) InitChain(params types.RequestInitChain) {
for _, v := range validators { for _, v := range params.Validators {
r := app.updateValidator(v) r := app.updateValidator(v)
if r.IsErr() { if r.IsErr() {
app.logger.Error("Error updating validators", "r", r) app.logger.Error("Error updating validators", "r", r)
@ -116,9 +116,9 @@ func (app *PersistentDummyApplication) InitChain(validators []*types.Validator)
} }
// Track the block hash and header information // Track the block hash and header information
func (app *PersistentDummyApplication) BeginBlock(hash []byte, header *types.Header) { func (app *PersistentDummyApplication) BeginBlock(params types.RequestBeginBlock) {
// update latest block info // update latest block info
app.blockHeader = header app.blockHeader = params.Header
// reset valset changes // reset valset changes
app.changes = make([]*types.Validator, 0) app.changes = make([]*types.Validator, 0)

View File

@ -186,10 +186,10 @@ func (s *SocketServer) handleRequest(req *types.Request, responses chan<- *types
resQuery := s.app.Query(*r.Query) resQuery := s.app.Query(*r.Query)
responses <- types.ToResponseQuery(resQuery) responses <- types.ToResponseQuery(resQuery)
case *types.Request_InitChain: case *types.Request_InitChain:
s.app.InitChain(r.InitChain.Validators) s.app.InitChain(*r.InitChain)
responses <- types.ToResponseInitChain() responses <- types.ToResponseInitChain()
case *types.Request_BeginBlock: case *types.Request_BeginBlock:
s.app.BeginBlock(r.BeginBlock.Hash, r.BeginBlock.Header) s.app.BeginBlock(*r.BeginBlock)
responses <- types.ToResponseBeginBlock() responses <- types.ToResponseBeginBlock()
case *types.Request_EndBlock: case *types.Request_EndBlock:
resEndBlock := s.app.EndBlock(r.EndBlock.Height) resEndBlock := s.app.EndBlock(r.EndBlock.Height)

View File

@ -4,19 +4,20 @@ import (
context "golang.org/x/net/context" context "golang.org/x/net/context"
) )
// Applications // Application is an interface that enables any finite, deterministic state machine
// to be driven by a blockchain-based replication engine via the ABCI
type Application interface { type Application interface {
// Info/Query Connection // Info/Query Connection
Info() ResponseInfo // Return application info Info() ResponseInfo // Return application info
SetOption(key string, value string) (log string) // Set application option SetOption(key string, value string) (log string) // Set application option
Query(reqQuery RequestQuery) ResponseQuery // Query for state Query(RequestQuery) ResponseQuery // Query for state
// Mempool Connection // Mempool Connection
CheckTx(tx []byte) Result // Validate a tx for the mempool CheckTx(tx []byte) Result // Validate a tx for the mempool
// Consensus Connection // Consensus Connection
InitChain(validators []*Validator) // Initialize blockchain with validators from TendermintCore InitChain(RequestInitChain) // Initialize blockchain with validators and other info from TendermintCore
BeginBlock(hash []byte, header *Header) // Signals the beginning of a block BeginBlock(RequestBeginBlock) // Signals the beginning of a block
DeliverTx(tx []byte) Result // Deliver a tx for full processing DeliverTx(tx []byte) Result // Deliver a tx for full processing
EndBlock(height uint64) ResponseEndBlock // Signals the end of a block, returns changes to the validator set EndBlock(height uint64) ResponseEndBlock // Signals the end of a block, returns changes to the validator set
Commit() Result // Commit the state and return the application Merkle root hash Commit() Result // Commit the state and return the application Merkle root hash
@ -24,7 +25,7 @@ type Application interface {
//------------------------------------ //------------------------------------
// GRPC wrapper for application // GRPCApplication is a GRPC wrapper for Application
type GRPCApplication struct { type GRPCApplication struct {
app Application app Application
} }
@ -71,12 +72,12 @@ func (app *GRPCApplication) Commit(ctx context.Context, req *RequestCommit) (*Re
} }
func (app *GRPCApplication) InitChain(ctx context.Context, req *RequestInitChain) (*ResponseInitChain, error) { func (app *GRPCApplication) InitChain(ctx context.Context, req *RequestInitChain) (*ResponseInitChain, error) {
app.app.InitChain(req.Validators) app.app.InitChain(*req)
return &ResponseInitChain{}, nil // NOTE: empty return return &ResponseInitChain{}, nil // NOTE: empty return
} }
func (app *GRPCApplication) BeginBlock(ctx context.Context, req *RequestBeginBlock) (*ResponseBeginBlock, error) { func (app *GRPCApplication) BeginBlock(ctx context.Context, req *RequestBeginBlock) (*ResponseBeginBlock, error) {
app.app.BeginBlock(req.Hash, req.Header) app.app.BeginBlock(*req)
return &ResponseBeginBlock{}, nil // NOTE: empty return return &ResponseBeginBlock{}, nil // NOTE: empty return
} }

View File

@ -31,10 +31,10 @@ func (app *BaseApplication) Query(reqQuery RequestQuery) (resQuery ResponseQuery
return return
} }
func (app *BaseApplication) InitChain(validators []*Validator) { func (app *BaseApplication) InitChain(reqInitChain RequestInitChain) {
} }
func (app *BaseApplication) BeginBlock(hash []byte, header *Header) { func (app *BaseApplication) BeginBlock(reqBeginBlock RequestBeginBlock) {
} }
func (app *BaseApplication) EndBlock(height uint64) (resEndBlock ResponseEndBlock) { func (app *BaseApplication) EndBlock(height uint64) (resEndBlock ResponseEndBlock) {

View File

@ -49,21 +49,21 @@ func ToRequestCommit() *Request {
} }
} }
func ToRequestQuery(reqQuery RequestQuery) *Request { func ToRequestQuery(req RequestQuery) *Request {
return &Request{ return &Request{
Value: &Request_Query{&reqQuery}, Value: &Request_Query{&req},
} }
} }
func ToRequestInitChain(validators []*Validator) *Request { func ToRequestInitChain(req RequestInitChain) *Request {
return &Request{ return &Request{
Value: &Request_InitChain{&RequestInitChain{validators}}, Value: &Request_InitChain{&req},
} }
} }
func ToRequestBeginBlock(hash []byte, header *Header) *Request { func ToRequestBeginBlock(req RequestBeginBlock) *Request {
return &Request{ return &Request{
Value: &Request_BeginBlock{&RequestBeginBlock{hash, header}}, Value: &Request_BeginBlock{&req},
} }
} }

View File

@ -6,6 +6,7 @@ import (
"github.com/tendermint/go-wire/data" "github.com/tendermint/go-wire/data"
) )
// Result is a common result object for ABCI calls.
// CONTRACT: a zero Result is OK. // CONTRACT: a zero Result is OK.
type Result struct { type Result struct {
Code CodeType `json:"code"` Code CodeType `json:"code"`