From cff9e9ae24df21361c89b3725c321e56c0e22722 Mon Sep 17 00:00:00 2001 From: Aaron Craelius Date: Wed, 19 Jan 2022 12:02:54 -0500 Subject: [PATCH] feat: make sdk.Context implement context.Context (#10941) ## Description This: * addresses an issue with the way `WrapSDKContext` was done in that it doesn't use the `context.Context` that is already inside `sdk.Context` * it allows `sdk.Context` to be used as a `context.Context` directly * it also walks back the deprecation of `Value` and `WithValue` from #4706 as I actually think these are useful, and trying to put everything directly into `Context` as a bag of variables rather than attaching it using something like `WithValue` makes the SDK less extensible --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [ ] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable) --- types/context.go | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/types/context.go b/types/context.go index ead23d2125..60aaa72144 100644 --- a/types/context.go +++ b/types/context.go @@ -23,7 +23,7 @@ but please do not over-use it. We try to keep all data structured and standard additions here would be better just to add to the Context struct */ type Context struct { - ctx context.Context + baseCtx context.Context ms MultiStore header tmproto.Header headerHash tmbytes.HexBytes @@ -44,7 +44,7 @@ type Context struct { type Request = Context // Read-only accessors -func (c Context) Context() context.Context { return c.ctx } +func (c Context) Context() context.Context { return c.baseCtx } func (c Context) MultiStore() MultiStore { return c.ms } func (c Context) BlockHeight() int64 { return c.header.Height } func (c Context) BlockTime() time.Time { return c.header.Time } @@ -76,12 +76,24 @@ func (c Context) ConsensusParams() *tmproto.ConsensusParams { return proto.Clone(c.consParams).(*tmproto.ConsensusParams) } +func (c Context) Deadline() (deadline time.Time, ok bool) { + return c.baseCtx.Deadline() +} + +func (c Context) Done() <-chan struct{} { + return c.baseCtx.Done() +} + +func (c Context) Err() error { + return c.baseCtx.Err() +} + // create a new context func NewContext(ms MultiStore, header tmproto.Header, isCheckTx bool, logger log.Logger) Context { // https://github.com/gogo/protobuf/issues/519 header.Time = header.Time.UTC() return Context{ - ctx: context.Background(), + baseCtx: context.Background(), ms: ms, header: header, chainID: header.ChainID, @@ -95,7 +107,7 @@ func NewContext(ms MultiStore, header tmproto.Header, isCheckTx bool, logger log // WithContext returns a Context with an updated context.Context. func (c Context) WithContext(ctx context.Context) Context { - c.ctx = ctx + c.baseCtx = ctx return c } @@ -219,23 +231,13 @@ func (c Context) IsZero() bool { return c.ms == nil } -// WithValue is deprecated, provided for backwards compatibility -// Please use -// ctx = ctx.WithContext(context.WithValue(ctx.Context(), key, false)) -// instead of -// ctx = ctx.WithValue(key, false) func (c Context) WithValue(key, value interface{}) Context { - c.ctx = context.WithValue(c.ctx, key, value) + c.baseCtx = context.WithValue(c.baseCtx, key, value) return c } -// Value is deprecated, provided for backwards compatibility -// Please use -// ctx.Context().Value(key) -// instead of -// ctx.Value(key) func (c Context) Value(key interface{}) interface{} { - return c.ctx.Value(key) + return c.baseCtx.Value(key) } // ---------------------------------------------------------------------------- @@ -261,6 +263,8 @@ func (c Context) CacheContext() (cc Context, writeCache func()) { return cc, cms.Write } +var _ context.Context = Context{} + // ContextKey defines a type alias for a stdlib Context key. type ContextKey string @@ -272,12 +276,15 @@ const SdkContextKey ContextKey = "sdk-context" // stdlib context.Context parameter such as generated gRPC methods. To get the original // sdk.Context back, call UnwrapSDKContext. func WrapSDKContext(ctx Context) context.Context { - return context.WithValue(ctx.ctx, SdkContextKey, ctx) + return ctx } // UnwrapSDKContext retrieves a Context from a context.Context instance // attached with WrapSDKContext. It panics if a Context was not properly // attached func UnwrapSDKContext(ctx context.Context) Context { + if sdkCtx, ok := ctx.(Context); ok { + return sdkCtx + } return ctx.Value(SdkContextKey).(Context) }