Skip to content

Commit

Permalink
chore(postage): add RecoverBatchOwner and MustNewValidStamp (#4047)
Browse files Browse the repository at this point in the history
  • Loading branch information
vladopajic committed May 5, 2023
1 parent 83bb900 commit f16fa57
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 21 deletions.
29 changes: 17 additions & 12 deletions pkg/postage/stamp.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,8 @@ func (s *Stamp) UnmarshalBinary(buf []byte) error {
return nil
}

// toSignDigest creates a digest to represent the stamp which is to be signed by
// the owner.
func toSignDigest(addr, batchId, index, timestamp []byte) ([]byte, error) {
// ToSignDigest creates a digest to represent the stamp which is to be signed by the owner.
func ToSignDigest(addr, batchId, index, timestamp []byte) ([]byte, error) {
h := swarm.NewHasher()
_, err := h.Write(addr)
if err != nil {
Expand Down Expand Up @@ -168,15 +167,7 @@ func ValidStamp(batchStore Storer) ValidStampFn {
// the validity check is only meaningful in its association of a chunk
// this chunk address needs to be given as argument
func (s *Stamp) Valid(chunkAddr swarm.Address, ownerAddr []byte, depth, bucketDepth uint8, immutable bool) error {
toSign, err := toSignDigest(chunkAddr.Bytes(), s.batchID, s.index, s.timestamp)
if err != nil {
return err
}
signerPubkey, err := crypto.Recover(s.sig, toSign)
if err != nil {
return err
}
signerAddr, err := crypto.NewEthereumAddress(*signerPubkey)
signerAddr, err := RecoverBatchOwner(chunkAddr, s)
if err != nil {
return err
}
Expand All @@ -192,3 +183,17 @@ func (s *Stamp) Valid(chunkAddr swarm.Address, ownerAddr []byte, depth, bucketDe
}
return nil
}

// RecoverBatchOwner returns ethereum address that signed postage batch of supplied stamp.
func RecoverBatchOwner(chunkAddr swarm.Address, stamp swarm.Stamp) ([]byte, error) {
toSign, err := ToSignDigest(chunkAddr.Bytes(), stamp.BatchID(), stamp.Index(), stamp.Timestamp())
if err != nil {
return nil, err
}
signerPubkey, err := crypto.Recover(stamp.Sig(), toSign)
if err != nil {
return nil, err
}

return crypto.NewEthereumAddress(*signerPubkey)
}
2 changes: 1 addition & 1 deletion pkg/postage/stamper.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (st *stamper) Stamp(addr swarm.Address) (*Stamp, error) {
return nil, err
}

toSign, err := toSignDigest(
toSign, err := ToSignDigest(
addr.Bytes(),
st.issuer.data.BatchID,
batchIndex,
Expand Down
32 changes: 28 additions & 4 deletions pkg/postage/testing/stamp.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ import (
"encoding/binary"
"io"

"github.com/ethersphere/bee/pkg/crypto"
"github.com/ethersphere/bee/pkg/postage"
"github.com/ethersphere/bee/pkg/swarm"
)

const signatureSize = 65

// MustNewSignature will create a new random signature (65 byte slice). Panics
// on errors.
// MustNewSignature will create a new random signature (65 byte slice). Panics on errors.
func MustNewSignature() []byte {
sig := make([]byte, signatureSize)
_, err := io.ReadFull(crand.Reader, sig)
Expand All @@ -25,12 +26,35 @@ func MustNewSignature() []byte {
return sig
}

// MustNewStamp will generate a postage stamp with random data. Panics on
// errors.
// MustNewValidSignature will create a new valid signature. Panics on errors.
func MustNewValidSignature(signer crypto.Signer, addr swarm.Address, id, index, timestamp []byte) []byte {
digest, err := postage.ToSignDigest(addr.Bytes(), id, index, timestamp)
if err != nil {
panic(err)
}

sig, err := signer.Sign(digest)
if err != nil {
panic(err)
}

return sig
}

// MustNewStamp will generate a invalid postage stamp with random data. Panics on errors.
func MustNewStamp() *postage.Stamp {
return postage.NewStamp(MustNewID(), MustNewID()[:8], MustNewID()[:8], MustNewSignature())
}

// MustNewValidStamp will generate a valid postage stamp with random data. Panics on errors.
func MustNewValidStamp(signer crypto.Signer, addr swarm.Address) *postage.Stamp {
id := MustNewID()
index := MustNewID()[:8]
timestamp := MustNewID()[:8]
sig := MustNewValidSignature(signer, addr, id, index, timestamp)
return postage.NewStamp(id, index, timestamp, sig)
}

// MustNewBatchStamp will generate a postage stamp with the provided batch ID and assign
// random data to other fields. Panics on error
func MustNewBatchStamp(batch []byte) *postage.Stamp {
Expand Down
19 changes: 15 additions & 4 deletions pkg/storage/testing/chunk.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,14 @@ import (

// GenerateTestRandomChunk generates a valid content addressed chunk.
func GenerateTestRandomChunk() swarm.Chunk {
key, _ := crypto.GenerateSecp256k1Key()
signer := crypto.NewDefaultSigner(key)

data := make([]byte, swarm.ChunkSize)
_, _ = rand.Read(data)
ch, _ := cac.New(data)
stamp := postagetesting.MustNewStamp()
stamp := postagetesting.MustNewValidStamp(signer, ch.Address())

return ch.WithStamp(stamp)
}

Expand All @@ -43,11 +47,18 @@ func GenerateTestRandomChunk() swarm.Chunk {
func GenerateTestRandomSoChunk(tb testing.TB, cac swarm.Chunk) swarm.Chunk {
tb.Helper()

id := testutil.RandBytes(tb, swarm.HashSize)
key, _ := crypto.GenerateSecp256k1Key()
signer := crypto.NewDefaultSigner(key)
ch, _ := soc.New(id, cac).Sign(signer)
return ch.WithStamp(postagetesting.MustNewStamp())
id := testutil.RandBytes(tb, swarm.HashSize)

ch, err := soc.New(id, cac).Sign(signer)
if err != nil {
tb.Fatal(err)
}

stamp := postagetesting.MustNewValidStamp(signer, ch.Address())

return ch.WithStamp(stamp)
}

// GenerateTestRandomInvalidChunk generates a random, however invalid, content
Expand Down

0 comments on commit f16fa57

Please sign in to comment.