Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DEMO: don't merge] Simple context #835

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Breaking changes
- Unify all message paths to follow pattern `<package>/<message_name>`
- `app.Router` interface was changed. Handler registration requires a message
and not message path.
- Pull out BlockInfo from weave.Context, add additional argument to all Handlers
and Decorators: `Deliver(context.Context, weave.BlockInfo, weave.KVStore, weave.Tx)`

## 0.17.0

Expand Down
14 changes: 8 additions & 6 deletions app/base.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package app

import (
"context"

"github.com/iov-one/weave"
"github.com/iov-one/weave/errors"
abci "github.com/tendermint/tendermint/abci/types"
Expand Down Expand Up @@ -39,11 +41,11 @@ func (b BaseApp) DeliverTx(txBytes []byte) abci.ResponseDeliverTx {
}

// ignore error here, allow it to be logged
ctx := weave.WithLogInfo(b.BlockContext(),
info := b.BlockInfo().WithLogInfo(
"call", "deliver_tx",
"path", weave.GetPath(tx))

res, err := b.handler.Deliver(ctx, b.DeliverStore(), tx)
res, err := b.handler.Deliver(context.Background(), info, b.DeliverStore(), tx)
if err == nil {
b.AddValChange(res.Diff)
}
Expand All @@ -57,11 +59,11 @@ func (b BaseApp) CheckTx(txBytes []byte) abci.ResponseCheckTx {
return weave.CheckTxError(err, b.debug)
}

ctx := weave.WithLogInfo(b.BlockContext(),
info := b.BlockInfo().WithLogInfo(
"call", "check_tx",
"path", weave.GetPath(tx))

res, err := b.handler.Check(ctx, b.CheckStore(), tx)
res, err := b.handler.Check(context.Background(), info, b.CheckStore(), tx)
return weave.CheckOrError(res, err, b.debug)
}

Expand All @@ -76,8 +78,8 @@ func (b BaseApp) BeginBlock(req abci.RequestBeginBlock) (
if b.ticker != nil {
// start := time.Now()
// Add info to the logger
ctx := weave.WithLogInfo(b.BlockContext(), "call", "begin_block")
res, err := b.ticker.Tick(ctx, b.DeliverStore())
info := b.BlockInfo().WithLogInfo("call", "begin_block")
res, err := b.ticker.Tick(context.Background(), info, b.DeliverStore())
// logDuration(ctx, start, "Ticker", err, false)
if err != nil {
panic(err)
Expand Down
9 changes: 5 additions & 4 deletions app/chain.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app

import (
"context"
"reflect"

"github.com/iov-one/weave"
Expand Down Expand Up @@ -76,11 +77,11 @@ type step struct {
var _ weave.Handler = step{}

// Check passes the handler into the decorator, implements Handler
func (s step) Check(ctx weave.Context, store weave.KVStore, tx weave.Tx) (*weave.CheckResult, error) {
return s.d.Check(ctx, store, tx, s.next)
func (s step) Check(ctx context.Context, info weave.BlockInfo, store weave.KVStore, tx weave.Tx) (*weave.CheckResult, error) {
return s.d.Check(ctx, info, store, tx, s.next)
}

// Deliver passes the handler into the decorator, implements Handler
func (s step) Deliver(ctx weave.Context, store weave.KVStore, tx weave.Tx) (*weave.DeliverResult, error) {
return s.d.Deliver(ctx, store, tx, s.next)
func (s step) Deliver(ctx context.Context, info weave.BlockInfo, store weave.KVStore, tx weave.Tx) (*weave.DeliverResult, error) {
return s.d.Deliver(ctx, info, store, tx, s.next)
}
25 changes: 13 additions & 12 deletions app/chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,33 +29,34 @@ func TestChain(t *testing.T) {
).WithHandler(h)

// This height must not panic.
ctx := weave.WithHeight(context.Background(), panicHeight-2)
ctx := context.Background()
info := weavetest.BlockInfo(panicHeight - 2)

_, err := stack.Check(ctx, nil, nil)
_, err := stack.Check(ctx, info, nil, nil)
assert.NoError(t, err)
assert.Equal(t, 1, c1.CheckCallCount())
assert.Equal(t, 1, c2.CheckCallCount())
assert.Equal(t, 1, c3.CheckCallCount())
assert.Equal(t, 1, h.CheckCallCount())

_, err = stack.Deliver(ctx, nil, nil)
_, err = stack.Deliver(ctx, info, nil, nil)
assert.NoError(t, err)
assert.Equal(t, 1, c1.DeliverCallCount())
assert.Equal(t, 1, c2.DeliverCallCount())
assert.Equal(t, 1, c3.DeliverCallCount())
assert.Equal(t, 1, h.DeliverCallCount())

// Trigger a panic.
ctx = weave.WithHeight(context.Background(), panicHeight+2)
info = weavetest.BlockInfo(panicHeight + 2)

_, err = stack.Check(ctx, nil, nil)
_, err = stack.Check(ctx, info, nil, nil)
assert.Error(t, err)
assert.Equal(t, 2, c1.CheckCallCount())
assert.Equal(t, 2, c2.CheckCallCount())
assert.Equal(t, 1, c3.CheckCallCount())
assert.Equal(t, 1, h.CheckCallCount())

_, err = stack.Deliver(ctx, nil, nil)
_, err = stack.Deliver(ctx, info, nil, nil)
assert.Error(t, err)
assert.Equal(t, 2, c1.DeliverCallCount())
assert.Equal(t, 2, c2.DeliverCallCount())
Expand All @@ -67,18 +68,18 @@ type panicAtHeightDecorator int64

var _ weave.Decorator = panicAtHeightDecorator(0)

func (ph panicAtHeightDecorator) Check(ctx weave.Context, db weave.KVStore, tx weave.Tx, next weave.Checker) (*weave.CheckResult, error) {
if val, _ := weave.GetHeight(ctx); val >= int64(ph) {
func (ph panicAtHeightDecorator) Check(ctx context.Context, info weave.BlockInfo, db weave.KVStore, tx weave.Tx, next weave.Checker) (*weave.CheckResult, error) {
if info.Height() >= int64(ph) {
panic("too high")
}
return next.Check(ctx, db, tx)
return next.Check(ctx, info, db, tx)
}

func (ph panicAtHeightDecorator) Deliver(ctx weave.Context, db weave.KVStore, tx weave.Tx, next weave.Deliverer) (*weave.DeliverResult, error) {
if val, _ := weave.GetHeight(ctx); val >= int64(ph) {
func (ph panicAtHeightDecorator) Deliver(ctx context.Context, info weave.BlockInfo, db weave.KVStore, tx weave.Tx, next weave.Deliverer) (*weave.DeliverResult, error) {
if info.Height() >= int64(ph) {
panic("too high")
}
return next.Deliver(ctx, db, tx)
return next.Deliver(ctx, info, db, tx)
}

func TestChainNilDecorator(t *testing.T) {
Expand Down
13 changes: 7 additions & 6 deletions app/router.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app

import (
"context"
"fmt"
"regexp"

Expand Down Expand Up @@ -57,33 +58,33 @@ func (r *Router) handler(m weave.Msg) weave.Handler {
}

// Check dispatches to the proper handler based on path
func (r *Router) Check(ctx weave.Context, store weave.KVStore, tx weave.Tx) (*weave.CheckResult, error) {
func (r *Router) Check(ctx context.Context, info weave.BlockInfo, store weave.KVStore, tx weave.Tx) (*weave.CheckResult, error) {
msg, err := tx.GetMsg()
if err != nil {
return nil, errors.Wrap(err, "cannot load msg")
}
h := r.handler(msg)
return h.Check(ctx, store, tx)
return h.Check(ctx, info, store, tx)
}

// Deliver dispatches to the proper handler based on path
func (r *Router) Deliver(ctx weave.Context, store weave.KVStore, tx weave.Tx) (*weave.DeliverResult, error) {
func (r *Router) Deliver(ctx context.Context, info weave.BlockInfo, store weave.KVStore, tx weave.Tx) (*weave.DeliverResult, error) {
msg, err := tx.GetMsg()
if err != nil {
return nil, errors.Wrap(err, "cannot load msg")
}
h := r.handler(msg)
return h.Deliver(ctx, store, tx)
return h.Deliver(ctx, info, store, tx)
}

// notFoundHandler always returns ErrNotFound error regardless of the arguments
// provided.
type notFoundHandler string

func (path notFoundHandler) Check(ctx weave.Context, store weave.KVStore, tx weave.Tx) (*weave.CheckResult, error) {
func (path notFoundHandler) Check(ctx context.Context, info weave.BlockInfo, store weave.KVStore, tx weave.Tx) (*weave.CheckResult, error) {
return nil, errors.Wrapf(errors.ErrNotFound, "no handler for message path %q", path)
}

func (path notFoundHandler) Deliver(ctx weave.Context, store weave.KVStore, tx weave.Tx) (*weave.DeliverResult, error) {
func (path notFoundHandler) Deliver(ctx context.Context, info weave.BlockInfo, store weave.KVStore, tx weave.Tx) (*weave.DeliverResult, error) {
return nil, errors.Wrapf(errors.ErrNotFound, "no handler for message path %q", path)
}
10 changes: 6 additions & 4 deletions app/router_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ func TestRouterSuccess(t *testing.T) {
)

r.Handle(msg, handler)
info := weavetest.BlockInfo(44)

if _, err := r.Check(context.TODO(), nil, &weavetest.Tx{Msg: msg}); err != nil {
if _, err := r.Check(context.TODO(), info, nil, &weavetest.Tx{Msg: msg}); err != nil {
t.Fatalf("check failed: %s", err)
}
if _, err := r.Deliver(context.TODO(), nil, &weavetest.Tx{Msg: msg}); err != nil {
if _, err := r.Deliver(context.TODO(), info, nil, &weavetest.Tx{Msg: msg}); err != nil {
t.Fatalf("delivery failed: %s", err)
}
assert.Equal(t, 2, handler.CallCount())
Expand All @@ -32,11 +33,12 @@ func TestRouterNoHandler(t *testing.T) {
r := NewRouter()

tx := &weavetest.Tx{Msg: &weavetest.Msg{RoutePath: "test/secret"}}
info := weavetest.BlockInfo(44)

if _, err := r.Check(context.TODO(), nil, tx); !errors.ErrNotFound.Is(err) {
if _, err := r.Check(context.TODO(), info, nil, tx); !errors.ErrNotFound.Is(err) {
t.Fatalf("expected not found error, got %s", err)
}
if _, err := r.Deliver(context.TODO(), nil, tx); !errors.ErrNotFound.Is(err) {
if _, err := r.Deliver(context.TODO(), info, nil, tx); !errors.ErrNotFound.Is(err) {
t.Fatalf("expected not found error, got %s", err)
}
}
Expand Down
55 changes: 24 additions & 31 deletions app/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,42 +45,38 @@ type StoreApp struct {
// cached validator changes from DeliverTx
pending weave.ValidatorUpdates

// baseContext contains context info that is valid for
// lifetime of this app (eg. chainID)
baseContext weave.Context

// blockContext contains context info that is valid for the
// blockInfo contains context info that is valid for the
// current block (eg. height, header), reset on BeginBlock
blockContext weave.Context
blockInfo weave.BlockInfo
}

// NewStoreApp initializes this app into a ready state with some defaults
//
// panics if unable to properly load the state from the given store
// TODO: is this correct? nothing else to do really....
func NewStoreApp(name string, store weave.CommitKVStore,
queryRouter weave.QueryRouter, baseContext weave.Context) *StoreApp {
func NewStoreApp(name string, store weave.CommitKVStore, queryRouter weave.QueryRouter) *StoreApp {
s := &StoreApp{
name: name,
// note: panics if trouble initializing from store
store: NewCommitStore(store),
queryRouter: queryRouter,
baseContext: baseContext,
logger: log.NewNopLogger(),
}
s = s.WithLogger(log.NewNopLogger())

// load the chainID from the db
s.chainID = mustLoadChainID(s.DeliverStore())
if s.chainID != "" {
s.baseContext = weave.WithChainID(s.baseContext, s.chainID)
}

// get the most recent height
info, err := s.store.CommitInfo()
if err != nil {
panic(err)
}
s.blockContext = weave.WithHeight(s.baseContext, info.Version)
// on first startup, we have no chainID to add, we will set blockInfo in Init
if s.chainID != "" {
s.blockInfo, err = weave.NewBlockInfo(abci.Header{Height: info.Version}, weave.CommitInfo{}, s.chainID, s.logger)
if s.chainID != "" && err != nil {
panic(err)
}
}
return s
}

Expand Down Expand Up @@ -120,17 +116,14 @@ func (s *StoreApp) parseAppState(data []byte, params weave.GenesisParams, chainI
return init.FromGenesis(appState, params, s.DeliverStore())
}

// store chainID and update context
// store chainID
func (s *StoreApp) storeChainID(chainID string) error {
// set the chainID
s.chainID = chainID
err := saveChainID(s.DeliverStore(), s.chainID)
if err != nil {
return err
}
// and update the context
s.baseContext = weave.WithChainID(s.baseContext, s.chainID)

return nil
}

Expand All @@ -139,7 +132,6 @@ func (s *StoreApp) storeChainID(chainID string) error {
//
// also sets baseContext logger
func (s *StoreApp) WithLogger(logger log.Logger) *StoreApp {
s.baseContext = weave.WithLogger(s.baseContext, logger)
s.logger = logger
return s
}
Expand All @@ -150,8 +142,8 @@ func (s *StoreApp) Logger() log.Logger {
}

// BlockContext returns the block context for public use
func (s *StoreApp) BlockContext() weave.Context {
return s.blockContext
func (s *StoreApp) BlockInfo() weave.BlockInfo {
return s.blockInfo
}

// DeliverStore returns the current DeliverTx cache for methods
Expand Down Expand Up @@ -307,15 +299,18 @@ func (s *StoreApp) Commit() (res abci.ResponseCommit) {
}

// InitChain implements ABCI
// Note: in tendermint 0.17, the genesis file is passed
// in here, we should use this to trigger reading the genesis now
// TODO: investigate validators and consensusParams in response
func (s *StoreApp) InitChain(req abci.RequestInitChain) (res abci.ResponseInitChain) {
err := s.parseAppState(req.AppStateBytes, weave.FromInitChain(req), req.ChainId, s.initializer)
if err != nil {
// Read comment on type header
panic(err)
}
s.blockInfo, err = weave.NewBlockInfo(abci.Header{Height: 0}, weave.CommitInfo{}, s.chainID, s.logger)
if err != nil {
// Read comment on type header
panic(err)
}

return abci.ResponseInitChain{}
}
Expand All @@ -324,17 +319,15 @@ func (s *StoreApp) InitChain(req abci.RequestInitChain) (res abci.ResponseInitCh
// Sets up blockContext
// TODO: investigate response tags as of 0.11 abci
func (s *StoreApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeginBlock) {
// set the begin block context
ctx := weave.WithHeader(s.baseContext, req.Header)
ctx = weave.WithHeight(ctx, req.Header.GetHeight())
ctx = weave.WithCommitInfo(ctx, req.LastCommitInfo)

var err error
s.blockInfo, err = weave.NewBlockInfo(req.Header, req.LastCommitInfo, s.chainID, s.logger)
if err != nil {
panic(err)
}
now := req.Header.GetTime()
if now.IsZero() {
panic("current time not found in the block header")
}
ctx = weave.WithBlockTime(ctx, now)
s.blockContext = ctx
return res
}

Expand Down
3 changes: 1 addition & 2 deletions app/store_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package app

import (
"context"
"testing"

"github.com/iov-one/weave"
Expand All @@ -19,7 +18,7 @@ func TestAddValChange(t *testing.T) {
Type: "test",
Data: []byte("someKey2"),
}
app := NewStoreApp("dummy", iavl.MockCommitStore(), weave.NewQueryRouter(), context.Background())
app := NewStoreApp("dummy", iavl.MockCommitStore(), weave.NewQueryRouter())

t.Run("Diff is equal to output with one update", func(t *testing.T) {
diff := []weave.ValidatorUpdate{
Expand Down
Loading