Skip to content

Commit

Permalink
feat: stamper index assignment rule update
Browse files Browse the repository at this point in the history
  • Loading branch information
acha-bill committed Jan 22, 2024
1 parent 657f7ab commit bf3c78e
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 20 deletions.
24 changes: 13 additions & 11 deletions pkg/postage/stamper.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package postage
import (
"errors"
"fmt"
"resenje.org/multex"

"github.com/ethersphere/bee/pkg/crypto"
"github.com/ethersphere/bee/pkg/storage"
Expand All @@ -15,8 +16,7 @@ import (

var (
// ErrBucketFull is the error when a collision bucket is full.
ErrBucketFull = errors.New("bucket full")
ErrOverwriteImmutableIndex = errors.New("immutable batch old index overwrite due to previous faulty save")
ErrBucketFull = errors.New("bucket full")
)

// Stamper can issue stamps from the given address of chunk.
Expand All @@ -30,31 +30,33 @@ type stamper struct {
store storage.Store
issuer *StampIssuer
signer crypto.Signer
mu *multex.Multex
}

// NewStamper constructs a Stamper.
func NewStamper(store storage.Store, issuer *StampIssuer, signer crypto.Signer) Stamper {
return &stamper{store, issuer, signer}
return &stamper{store, issuer, signer, multex.New()}
}

// Stamp takes chunk, see if the chunk can included in the batch and
// Stamp takes chunk, see if the chunk can be included in the batch and
// signs it with the owner of the batch of this Stamp issuer.
func (st *stamper) Stamp(addr swarm.Address) (*Stamp, error) {
st.mu.Lock(addr.ByteString())
defer st.mu.Unlock(addr.ByteString())

item := &StampItem{
BatchID: st.issuer.data.BatchID,
chunkAddress: addr,
}
switch err := st.store.Get(item); {
case err == nil:
// The index should be in the past. It could happen that we encountered
// some error after assigning this index and did not save the issuer data. In
// this case we should assign a new index and update it.
if st.issuer.assigned(item.BatchIndex) {
if st.issuer.assigned(item.BatchIndex) || st.issuer.ImmutableFlag() {
break
} else if st.issuer.ImmutableFlag() {
return nil, ErrOverwriteImmutableIndex
}
fallthrough
item.BatchTimestamp = unixTime()
if err = st.store.Put(item); err != nil {
return nil, err
}
case errors.Is(err, storage.ErrNotFound):
item.BatchIndex, item.BatchTimestamp, err = st.issuer.increment(addr)
if err != nil {
Expand Down
30 changes: 21 additions & 9 deletions pkg/postage/stamper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,11 @@ func TestStamperStamping(t *testing.T) {
}
})

t.Run("incorrect old index", func(t *testing.T) {
t.Run("reuse index but get new timestamp for mutable batch", func(t *testing.T) {
st := newTestStampIssuerMutability(t, 1000, false)
chunkAddr := swarm.RandAddress(t)
bIdx := postage.ToBucket(st.BucketDepth(), chunkAddr)
index := postage.IndexToBytes(bIdx, 100)
index := postage.IndexToBytes(bIdx, 4)
testItem := postage.NewStampItem().
WithBatchID(st.ID()).
WithChunkAddress(chunkAddr).
Expand All @@ -124,25 +124,37 @@ func TestStamperStamping(t *testing.T) {
if err := stamp.Valid(chunkAddr, owner, 12, 8, true); err != nil {
t.Fatalf("expected no error, got %v", err)
}
if bytes.Equal(stamp.Index(), testItem.BatchIndex) {
t.Fatalf("expected index to be different, got %x", stamp.Index())
if bytes.Equal(stamp.Timestamp(), testItem.BatchTimestamp) {
t.Fatalf("expected timestamp to be different, got %x", stamp.Index())
}
if !bytes.Equal(stamp.Index(), testItem.BatchIndex) {
t.Fatalf("expected index to be the same, got %x", stamp.Index())
}
})

t.Run("incorrect old index immutable", func(t *testing.T) {
t.Run("reuse same index and timestamp for immutable batch", func(t *testing.T) {
st := newTestStampIssuerMutability(t, 1000, true)
chunkAddr := swarm.RandAddress(t)
bIdx := postage.ToBucket(st.BucketDepth(), chunkAddr)
index := postage.IndexToBytes(bIdx, 100)
index := postage.IndexToBytes(bIdx, 4)
testItem := postage.NewStampItem().
WithBatchID(st.ID()).
WithChunkAddress(chunkAddr).
WithBatchIndex(index)
testSt := &testStore{Store: inmemstore.New(), stampItem: testItem}
stamper := postage.NewStamper(testSt, st, signer)
_, err := stamper.Stamp(chunkAddr)
if !errors.Is(err, postage.ErrOverwriteImmutableIndex) {
t.Fatalf("got err %v, wanted %v", err, postage.ErrOverwriteImmutableIndex)
stamp, err := stamper.Stamp(chunkAddr)
if err != nil {
t.Fatal(err)
}
if err := stamp.Valid(chunkAddr, owner, 12, 8, true); err != nil {
t.Fatalf("expected no error, got %v", err)
}
if !bytes.Equal(stamp.Timestamp(), testItem.BatchTimestamp) {
t.Fatalf("expected timestamp to be the same, got %x", stamp.Index())
}
if !bytes.Equal(stamp.Index(), testItem.BatchIndex) {
t.Fatalf("expected index to be the same, got %x", stamp.Index())
}
})

Expand Down

0 comments on commit bf3c78e

Please sign in to comment.