Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronc committed May 29, 2021
1 parent da9ea79 commit b0a9347
Show file tree
Hide file tree
Showing 15 changed files with 792 additions and 271 deletions.
67 changes: 67 additions & 0 deletions core/abci/app_base.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package abci

import (
"context"

"github.com/tendermint/tendermint/abci/types"
)

type AppBase struct {
handler Handler
checkCtx context.Context
deliverCtx context.Context
}

var _ types.Application = AppBase{}

func (a AppBase) Info(info types.RequestInfo) types.ResponseInfo {
return a.handler.Info(a.checkCtx, info)
}

func (a AppBase) SetOption(option types.RequestSetOption) types.ResponseSetOption {
return a.handler.SetOption(a.checkCtx, option)
}

func (a AppBase) Query(query types.RequestQuery) types.ResponseQuery {
return a.handler.Query(a.checkCtx, query)
}

func (a AppBase) CheckTx(tx types.RequestCheckTx) types.ResponseCheckTx {
return a.handler.CheckTx(a.checkCtx, tx)
}

func (a AppBase) InitChain(chain types.RequestInitChain) types.ResponseInitChain {
return a.handler.InitChain(a.deliverCtx, chain)
}

func (a AppBase) BeginBlock(block types.RequestBeginBlock) types.ResponseBeginBlock {
return a.handler.BeginBlock(a.deliverCtx, block)
}

func (a AppBase) DeliverTx(tx types.RequestDeliverTx) types.ResponseDeliverTx {
return a.handler.DeliverTx(a.deliverCtx, tx)
}

func (a AppBase) EndBlock(block types.RequestEndBlock) types.ResponseEndBlock {
return a.handler.EndBlock(a.deliverCtx, block)
}

func (a AppBase) Commit() types.ResponseCommit {
return a.handler.Commit(a.deliverCtx)
}

func (a AppBase) ListSnapshots(snapshots types.RequestListSnapshots) types.ResponseListSnapshots {
return a.handler.ListSnapshots(a.checkCtx, snapshots)
}

func (a AppBase) OfferSnapshot(snapshot types.RequestOfferSnapshot) types.ResponseOfferSnapshot {
return a.handler.OfferSnapshot(a.checkCtx, snapshot)
}

func (a AppBase) LoadSnapshotChunk(chunk types.RequestLoadSnapshotChunk) types.ResponseLoadSnapshotChunk {
return a.handler.LoadSnapshotChunk(a.checkCtx, chunk)
}

func (a AppBase) ApplySnapshotChunk(chunk types.RequestApplySnapshotChunk) types.ResponseApplySnapshotChunk {
return a.handler.ApplySnapshotChunk(a.checkCtx, chunk)
}
5 changes: 5 additions & 0 deletions core/abci/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package config

type Config struct {
Middleware []interface{}
}
30 changes: 30 additions & 0 deletions core/abci/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package abci

import (
"context"

types "github.com/tendermint/tendermint/abci/types"
)

type Handler interface {
// Info/Query Connection
Info(ctx context.Context, req types.RequestInfo) types.ResponseInfo // Return application info
SetOption(ctx context.Context, req types.RequestSetOption) types.ResponseSetOption // Set application option
Query(ctx context.Context, req types.RequestQuery) types.ResponseQuery // Query for state

// Mempool Connection
CheckTx(ctx context.Context, req types.RequestCheckTx) types.ResponseCheckTx // Validate a tx for the mempool

// Consensus Connection
InitChain(ctx context.Context, req types.RequestInitChain) types.ResponseInitChain // Initialize blockchain w validators/other info from TendermintCore
BeginBlock(ctx context.Context, req types.RequestBeginBlock) types.ResponseBeginBlock // Signals the beginning of a block
DeliverTx(ctx context.Context, req types.RequestDeliverTx) types.ResponseDeliverTx // Deliver a tx for full processing
EndBlock(ctx context.Context, req types.RequestEndBlock) types.ResponseEndBlock // Signals the end of a block, returns changes to the validator set
Commit(context.Context) types.ResponseCommit // Commit the state and return the application Merkle root hash

// State Sync Connection
ListSnapshots(ctx context.Context, req types.RequestListSnapshots) types.ResponseListSnapshots // List available snapshots
OfferSnapshot(ctx context.Context, req types.RequestOfferSnapshot) types.ResponseOfferSnapshot // Offer a snapshot to the application
LoadSnapshotChunk(ctx context.Context, req types.RequestLoadSnapshotChunk) types.ResponseLoadSnapshotChunk // Load a snapshot chunk
ApplySnapshotChunk(ctx context.Context, req types.RequestApplySnapshotChunk) types.ResponseApplySnapshotChunk // Apply a shapshot chunk
}
63 changes: 63 additions & 0 deletions core/abci/handler_base.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package abci

import (
"context"

"github.com/tendermint/tendermint/abci/types"
)

type HandlerBase struct{}

func (h HandlerBase) Info(context.Context, types.RequestInfo) types.ResponseInfo {
return types.ResponseInfo{}
}

func (h HandlerBase) SetOption(context.Context, types.RequestSetOption) types.ResponseSetOption {
return types.ResponseSetOption{}
}

func (h HandlerBase) Query(context.Context, types.RequestQuery) types.ResponseQuery {
return types.ResponseQuery{}
}

func (h HandlerBase) CheckTx(context.Context, types.RequestCheckTx) types.ResponseCheckTx {
return types.ResponseCheckTx{}
}

func (h HandlerBase) InitChain(context.Context, types.RequestInitChain) types.ResponseInitChain {
return types.ResponseInitChain{}
}

func (h HandlerBase) BeginBlock(context.Context, types.RequestBeginBlock) types.ResponseBeginBlock {
return types.ResponseBeginBlock{}
}

func (h HandlerBase) DeliverTx(context.Context, types.RequestDeliverTx) types.ResponseDeliverTx {
return types.ResponseDeliverTx{}
}

func (h HandlerBase) EndBlock(context.Context, types.RequestEndBlock) types.ResponseEndBlock {
return types.ResponseEndBlock{}
}

func (h HandlerBase) Commit(context.Context) types.ResponseCommit {
return types.ResponseCommit{}
}

func (h HandlerBase) ListSnapshots(context.Context, types.RequestListSnapshots) types.ResponseListSnapshots {
return types.ResponseListSnapshots{}
}

func (h HandlerBase) OfferSnapshot(context.Context, types.RequestOfferSnapshot) types.ResponseOfferSnapshot {
return types.ResponseOfferSnapshot{}
}

func (h HandlerBase) LoadSnapshotChunk(context.Context, types.RequestLoadSnapshotChunk) types.ResponseLoadSnapshotChunk {
return types.ResponseLoadSnapshotChunk{}
}

func (h HandlerBase) ApplySnapshotChunk(context.Context, types.RequestApplySnapshotChunk) types.ResponseApplySnapshotChunk {
return types.ResponseApplySnapshotChunk{}
}

var _ Handler = HandlerBase{}
88 changes: 88 additions & 0 deletions core/abci/header/header.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package header

import (
"context"
"fmt"

tmproto "github.com/tendermint/tendermint/proto/tendermint/types"

sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/tendermint/tendermint/abci/types"

"github.com/cosmos/cosmos-sdk/core/abci"
)

var Middleware abci.Middleware = func(handler abci.Handler) abci.Handler {
return &middleware{
Handler: handler,
}
}

type middleware struct {
abci.Handler
initialHeight int64
lastBlockHeight int64
}

func (m *middleware) InitChain(ctx context.Context, req types.RequestInitChain) types.ResponseInitChain {
// On a new chain, we consider the init chain block height as 0, even though
// req.InitialHeight is 1 by default.
initHeader := tmproto.Header{ChainID: req.ChainId, Time: req.Time}

// If req.InitialHeight is > 1, then we set the initial version in the
// stores.
if req.InitialHeight > 1 {
m.initialHeight = req.InitialHeight
initHeader = tmproto.Header{ChainID: req.ChainId, Height: req.InitialHeight, Time: req.Time}
}

sdkCtx := sdk.UnwrapSDKContext(ctx)
sdkCtx = sdkCtx.WithBlockHeader(initHeader)
ctx = context.WithValue(ctx, sdk.SdkContextKey, sdkCtx)

return m.Handler.InitChain(ctx, req)
}

func (m *middleware) BeginBlock(ctx context.Context, req types.RequestBeginBlock) types.ResponseBeginBlock {
if err := m.validateHeight(req); err != nil {
panic(err)
}

m.lastBlockHeight = req.Header.Height

sdkCtx := sdk.UnwrapSDKContext(ctx)
sdkCtx = sdkCtx.
WithBlockHeader(req.Header).
WithBlockHeight(req.Header.Height)
ctx = context.WithValue(ctx, sdk.SdkContextKey, sdkCtx)

return m.Handler.BeginBlock(ctx, req)
}

func (m middleware) validateHeight(req types.RequestBeginBlock) error {
if req.Header.Height < 1 {
return fmt.Errorf("invalid height: %d", req.Header.Height)
}

// expectedHeight holds the expected height to validate.
var expectedHeight int64
if m.lastBlockHeight == 0 && m.initialHeight > 1 {
// In this case, we're validating the first block of the chain (no
// previous commit). The height we're expecting is the initial height.
expectedHeight = m.initialHeight
} else {
// This case can means two things:
// - either there was already a previous commit in the store, in which
// case we increment the version from there,
// - or there was no previous commit, and initial version was not set,
// in which case we start at version 1.
expectedHeight = m.lastBlockHeight + 1
}

if req.Header.Height != expectedHeight {
return fmt.Errorf("invalid height: %d; expected: %d", req.Header.Height, expectedHeight)
}

return nil
}
3 changes: 3 additions & 0 deletions core/abci/middleware.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package abci

type Middleware func(Handler) Handler
Loading

0 comments on commit b0a9347

Please sign in to comment.