From b1c534f36c3702ea78bd57fb77ad19d00772740b Mon Sep 17 00:00:00 2001 From: testinginprod Date: Tue, 20 Dec 2022 12:00:40 +0100 Subject: [PATCH 1/4] feat(collections): add sequence --- collections/sequence.go | 51 ++++++++++++++++++++++++++++++++++++ collections/sequence_test.go | 32 ++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 collections/sequence.go create mode 100644 collections/sequence_test.go diff --git a/collections/sequence.go b/collections/sequence.go new file mode 100644 index 000000000000..e52e65e0c291 --- /dev/null +++ b/collections/sequence.go @@ -0,0 +1,51 @@ +package collections + +import ( + "context" + "errors" +) + +// DefaultSequenceStart defines the default starting number of a sequence. +const DefaultSequenceStart uint64 = 1 + +// Sequence builds on top of an Item, and represents +// an ever-increasing number. +type Sequence Item[uint64] + +// NewSequence instantiates a new sequence given +// a Schema, a Prefix and humanised name for the sequence. +func NewSequence(schema Schema, prefix Prefix, name string) Sequence { + return (Sequence)(NewItem(schema, prefix, name, Uint64Value)) +} + +// Peek returns the current sequence value, if no number +// is set then the DefaultSequenceStart is returned. +// Errors on encoding issues. +func (s Sequence) Peek(ctx context.Context) (uint64, error) { + n, err := (Item[uint64])(s).Get(ctx) + if err == nil { + return n, nil + } else { + if errors.Is(err, ErrNotFound) { + return DefaultSequenceStart, nil + } else { + return 0, err + } + } +} + +// Next returns the next sequence number, and sets the next expected sequence. +// Errors on encoding issues. +func (s Sequence) Next(ctx context.Context) (uint64, error) { + seq, err := s.Peek(ctx) + if err != nil { + return 0, err + } + return seq, s.Set(ctx, seq+1) +} + +// Set hard resets the sequence to the provided value. +// Errors on encoding issues. +func (s Sequence) Set(ctx context.Context, value uint64) error { + return (Item[uint64])(s).Set(ctx, value) +} diff --git a/collections/sequence_test.go b/collections/sequence_test.go new file mode 100644 index 000000000000..082e3000669c --- /dev/null +++ b/collections/sequence_test.go @@ -0,0 +1,32 @@ +package collections + +import ( + "github.com/stretchr/testify/require" + "testing" +) + +func TestSequence(t *testing.T) { + sk, ctx := deps() + schema := NewSchema(sk) + seq := NewSequence(schema, NewPrefix(0), "sequence") + // initially the first available number is DefaultSequenceStart + n, err := seq.Peek(ctx) + require.NoError(t, err) + require.Equal(t, DefaultSequenceStart, n) + + // when we call next when sequence is still unset the first expected value is DefaultSequenceStart + n, err = seq.Next(ctx) + require.NoError(t, err) + require.Equal(t, DefaultSequenceStart, n) + // when we call peek after the first number is set, then the next expected sequence is DefaultSequenceStart + 1 + n, err = seq.Peek(ctx) + require.NoError(t, err) + require.Equal(t, DefaultSequenceStart+1, n) + + // set + err = seq.Set(ctx, 10) + require.NoError(t, err) + n, err = seq.Peek(ctx) + require.NoError(t, err) + require.Equal(t, n, uint64(10)) +} From 5543a18ed7aa435d5d674014cd17108ee7c07130 Mon Sep 17 00:00:00 2001 From: testinginprod Date: Tue, 20 Dec 2022 12:03:36 +0100 Subject: [PATCH 2/4] chore: CHANGELOG.md --- collections/CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/collections/CHANGELOG.md b/collections/CHANGELOG.md index d49418598a79..b69be22353e9 100644 --- a/collections/CHANGELOG.md +++ b/collections/CHANGELOG.md @@ -32,4 +32,5 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## [Unreleased] * [#14134](https://github.com/cosmos/cosmos-sdk/pull/14134) Initialise core (Prefix, KeyEncoder, ValueEncoder, Map). -* [#14351](https://github.com/cosmos/cosmos-sdk/pull/14351) Add keyset \ No newline at end of file +* [#14351](https://github.com/cosmos/cosmos-sdk/pull/14351) Add keyset +* [#14364](https://github.com/cosmos/cosmos-sdk/pull/14364) Add sequence \ No newline at end of file From ebbe4f8f7f63cf893f630f0ed0a3ae0dfae24c84 Mon Sep 17 00:00:00 2001 From: testinginprod <98415576+testinginprod@users.noreply.github.com> Date: Tue, 20 Dec 2022 18:39:49 +0100 Subject: [PATCH 3/4] Update collections/sequence.go Co-authored-by: Aleksandr Bezobchuk --- collections/sequence.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/collections/sequence.go b/collections/sequence.go index e52e65e0c291..e2d5c4fe2e13 100644 --- a/collections/sequence.go +++ b/collections/sequence.go @@ -8,8 +8,7 @@ import ( // DefaultSequenceStart defines the default starting number of a sequence. const DefaultSequenceStart uint64 = 1 -// Sequence builds on top of an Item, and represents -// an ever-increasing number. +// Sequence builds on top of an Item, and represents a monotonically increasing value. type Sequence Item[uint64] // NewSequence instantiates a new sequence given From be16ce5e49f4370108e5e50745e8af749cf801af Mon Sep 17 00:00:00 2001 From: testinginprod Date: Tue, 20 Dec 2022 18:50:50 +0100 Subject: [PATCH 4/4] change: address feedback --- collections/sequence.go | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/collections/sequence.go b/collections/sequence.go index e2d5c4fe2e13..61be844fa45d 100644 --- a/collections/sequence.go +++ b/collections/sequence.go @@ -8,7 +8,7 @@ import ( // DefaultSequenceStart defines the default starting number of a sequence. const DefaultSequenceStart uint64 = 1 -// Sequence builds on top of an Item, and represents a monotonically increasing value. +// Sequence builds on top of an Item, and represents a monotonically increasing number. type Sequence Item[uint64] // NewSequence instantiates a new sequence given @@ -22,14 +22,13 @@ func NewSequence(schema Schema, prefix Prefix, name string) Sequence { // Errors on encoding issues. func (s Sequence) Peek(ctx context.Context) (uint64, error) { n, err := (Item[uint64])(s).Get(ctx) - if err == nil { + switch { + case err == nil: return n, nil - } else { - if errors.Is(err, ErrNotFound) { - return DefaultSequenceStart, nil - } else { - return 0, err - } + case errors.Is(err, ErrNotFound): + return DefaultSequenceStart, nil + default: + return 0, err } }