github.com/ethersphere/bee/v2@v2.2.0/pkg/postage/stamp_test.go (about)

     1  // Copyright 2020 The Swarm Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package postage_test
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/json"
    10  	"math/big"
    11  	"testing"
    12  
    13  	"github.com/ethersphere/bee/v2/pkg/crypto"
    14  	"github.com/ethersphere/bee/v2/pkg/postage"
    15  	"github.com/ethersphere/bee/v2/pkg/postage/batchstore/mock"
    16  	postagetesting "github.com/ethersphere/bee/v2/pkg/postage/testing"
    17  	"github.com/ethersphere/bee/v2/pkg/storage/inmemstore"
    18  	chunktesting "github.com/ethersphere/bee/v2/pkg/storage/testing"
    19  )
    20  
    21  // TestStampMarshalling tests the idempotence  of binary marshal/unmarshals for Stamps.
    22  func TestStampMarshalling(t *testing.T) {
    23  	sExp := postagetesting.MustNewStamp()
    24  	buf, _ := sExp.MarshalBinary()
    25  	if len(buf) != postage.StampSize {
    26  		t.Fatalf("invalid length for serialised stamp. expected %d, got  %d", postage.StampSize, len(buf))
    27  	}
    28  	s := postage.NewStamp(nil, nil, nil, nil)
    29  	if err := s.UnmarshalBinary(buf); err != nil {
    30  		t.Fatalf("unexpected error unmarshalling stamp: %v", err)
    31  	}
    32  	compareStamps(t, sExp, s)
    33  }
    34  
    35  // TestStampMarshalling tests the idempotence  of binary marshal/unmarshals for Stamps.
    36  func TestStampJsonMarshalling(t *testing.T) {
    37  	sExp := postagetesting.MustNewStamp()
    38  
    39  	b, err := json.Marshal(sExp)
    40  	if err != nil {
    41  		t.Fatal(err)
    42  	}
    43  
    44  	s := postage.NewStamp(nil, nil, nil, nil)
    45  	err = json.Unmarshal(b, s)
    46  	if err != nil {
    47  		t.Fatal(err)
    48  	}
    49  
    50  	compareStamps(t, sExp, s)
    51  }
    52  
    53  func compareStamps(t *testing.T, s1, s2 *postage.Stamp) {
    54  	t.Helper()
    55  
    56  	if !bytes.Equal(s1.BatchID(), s2.BatchID()) {
    57  		t.Fatalf("id mismatch, expected %x, got %x", s1.BatchID(), s2.BatchID())
    58  	}
    59  	if !bytes.Equal(s1.Index(), s2.Index()) {
    60  		t.Fatalf("index mismatch, expected %x, got %x", s1.Index(), s2.Index())
    61  	}
    62  	if !bytes.Equal(s1.Timestamp(), s2.Timestamp()) {
    63  		t.Fatalf("timestamp mismatch, expected %x, got %x", s1.Index(), s2.Index())
    64  	}
    65  	if !bytes.Equal(s1.Sig(), s2.Sig()) {
    66  		t.Fatalf("sig mismatch, expected %x, got %x", s1.Sig(), s2.Sig())
    67  	}
    68  }
    69  
    70  // TestStampIndexMarshalling tests the idempotence of stamp index serialisation.
    71  func TestStampIndexMarshalling(t *testing.T) {
    72  	var (
    73  		expBucket uint32 = 11789
    74  		expIndex  uint32 = 199999
    75  	)
    76  	index := postage.IndexToBytes(expBucket, expIndex)
    77  	bucket, idx := postage.BucketIndexFromBytes(index)
    78  	if bucket != expBucket {
    79  		t.Fatalf("bucket mismatch. want %d, got %d", expBucket, bucket)
    80  	}
    81  	if idx != expIndex {
    82  		t.Fatalf("index mismatch. want %d, got %d", expIndex, idx)
    83  	}
    84  }
    85  
    86  func TestValidStamp(t *testing.T) {
    87  	privKey, err := crypto.GenerateSecp256k1Key()
    88  	if err != nil {
    89  		t.Fatal(err)
    90  	}
    91  
    92  	owner, err := crypto.NewEthereumAddress(privKey.PublicKey)
    93  	if err != nil {
    94  		t.Fatal(err)
    95  	}
    96  	b := postagetesting.MustNewBatch(postagetesting.WithOwner(owner))
    97  	bs := mock.New(mock.WithBatch(b))
    98  	signer := crypto.NewDefaultSigner(privKey)
    99  	issuer := postage.NewStampIssuer("label", "keyID", b.ID, big.NewInt(3), b.Depth, b.BucketDepth, 1000, true)
   100  	stamper := postage.NewStamper(inmemstore.New(), issuer, signer)
   101  
   102  	// this creates a chunk with a mocked stamp. ValidStamp will override this
   103  	// stamp on execution
   104  	ch := chunktesting.GenerateTestRandomChunk()
   105  
   106  	st, err := stamper.Stamp(ch.Address())
   107  	if err != nil {
   108  		t.Fatal(err)
   109  	}
   110  
   111  	ch.WithStamp(st)
   112  
   113  	// ensure the chunk doesn't have the batch details filled before we validate stamp
   114  	if ch.Depth() == b.Depth || ch.BucketDepth() == b.BucketDepth {
   115  		t.Fatal("expected chunk to not have correct depth and bucket depth at start")
   116  	}
   117  
   118  	ch, err = postage.ValidStamp(bs)(ch)
   119  	if err != nil {
   120  		t.Fatal(err)
   121  	}
   122  
   123  	compareStamps(t, st, ch.Stamp().(*postage.Stamp))
   124  
   125  	if ch.Depth() != b.Depth {
   126  		t.Fatalf("invalid batch depth added on chunk exp %d got %d", b.Depth, ch.Depth())
   127  	}
   128  	if ch.BucketDepth() != b.BucketDepth {
   129  		t.Fatalf("invalid bucket depth added on chunk exp %d got %d", b.BucketDepth, ch.BucketDepth())
   130  	}
   131  	if ch.Immutable() != b.Immutable {
   132  		t.Fatalf("invalid batch immutablility added on chunk exp %t got %t", b.Immutable, ch.Immutable())
   133  	}
   134  }