From 52cd8ece85ebfee1d7e71242211ebee12d91cebc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Levente=20T=C3=B3th?= Date: Tue, 19 Dec 2023 16:18:50 +0100 Subject: [PATCH 1/6] feat: dispersed replica validation --- pkg/soc/validator.go | 7 +++++++ pkg/swarm/swarm.go | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/pkg/soc/validator.go b/pkg/soc/validator.go index a707eaded36..db0c388808e 100644 --- a/pkg/soc/validator.go +++ b/pkg/soc/validator.go @@ -5,6 +5,8 @@ package soc import ( + "bytes" + "github.com/ethersphere/bee/pkg/swarm" ) @@ -15,6 +17,11 @@ func Valid(ch swarm.Chunk) bool { return false } + // disperse replica validation + if bytes.Equal(s.owner, swarm.ReplicasOwner) && !bytes.Equal(s.WrappedChunk().Address().Bytes()[1:32], s.id[1:32]) { + return false + } + address, err := s.Address() if err != nil { return false diff --git a/pkg/swarm/swarm.go b/pkg/swarm/swarm.go index 7e8d514b095..94a7fe711e5 100644 --- a/pkg/swarm/swarm.go +++ b/pkg/swarm/swarm.go @@ -37,6 +37,12 @@ var ( ErrInvalidChunk = errors.New("invalid chunk") ) +var ( + // Ethereum Address of the for Dispersed Replicas writes + // generated from private key 0x0100000000000000000000000000000000000000000000000000000000000000 + ReplicasOwner, _ = hex.DecodeString("dc5b20847f43d67928f49cd4f85d696b5a7617b5") +) + var ( // EmptyAddress is the address that is all zeroes. EmptyAddress = NewAddress(make([]byte, HashSize)) From 024e0e6d71ebc10ff8999dab9b2c1e8ec8f1cdcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Levente=20T=C3=B3th?= Date: Tue, 19 Dec 2023 16:19:05 +0100 Subject: [PATCH 2/6] test: dispersed replica validation --- pkg/soc/validator_test.go | 58 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/pkg/soc/validator_test.go b/pkg/soc/validator_test.go index 18ed00001a4..695d43cc46f 100644 --- a/pkg/soc/validator_test.go +++ b/pkg/soc/validator_test.go @@ -5,9 +5,13 @@ package soc_test import ( + "crypto/rand" + "io" "strings" "testing" + "github.com/ethersphere/bee/pkg/cac" + "github.com/ethersphere/bee/pkg/crypto" "github.com/ethersphere/bee/pkg/soc" "github.com/ethersphere/bee/pkg/swarm" ) @@ -31,6 +35,60 @@ func TestValid(t *testing.T) { } } +// TestValidDispersedReplica verifies that the validator can detect +// valid dispersed replicas chunks. +func TestValidDispersedReplica(t *testing.T) { + t.Parallel() + + t.Run("valid", func(t *testing.T) { + privKey, _ := crypto.DecodeSecp256k1PrivateKey(append([]byte{1}, make([]byte, 31)...)) + signer := crypto.NewDefaultSigner(privKey) + + chData := make([]byte, swarm.ChunkSize) + _, _ = io.ReadFull(rand.Reader, chData) + ch, err := cac.New(chData) + if err != nil { + t.Fatal(err) + } + id := append([]byte{1}, ch.Address().Bytes()[1:]...) + + socCh, err := soc.New(id, ch).Sign(signer) + if err != nil { + t.Fatal(err) + } + + // check valid chunk + if !soc.Valid(socCh) { + t.Fatal("dispersed replica chunk is invalid") + } + }) + + t.Run("invalid", func(t *testing.T) { + privKey, _ := crypto.DecodeSecp256k1PrivateKey(append([]byte{1}, make([]byte, 31)...)) + signer := crypto.NewDefaultSigner(privKey) + + chData := make([]byte, swarm.ChunkSize) + _, _ = io.ReadFull(rand.Reader, chData) + ch, err := cac.New(chData) + if err != nil { + t.Fatal(err) + } + id := append([]byte{1}, ch.Address().Bytes()[1:]...) + // change to invalid ID + id[2] += 1 + + socCh, err := soc.New(id, ch).Sign(signer) + if err != nil { + t.Fatal(err) + } + + // check valid chunk + if soc.Valid(socCh) { + t.Fatal("dispersed replica should be invalid") + } + }) +} + // TestInvalid verifies that the validator can detect chunks // with invalid data and invalid address. func TestInvalid(t *testing.T) { From 54fb64a924945c831cc067b7585f37be30d9bfbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Levente=20T=C3=B3th?= Date: Tue, 19 Dec 2023 16:22:38 +0100 Subject: [PATCH 3/6] refactor: move owner to swarm package --- pkg/replicas/replicas.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pkg/replicas/replicas.go b/pkg/replicas/replicas.go index 0fbcee6857b..18b21d4b8b8 100644 --- a/pkg/replicas/replicas.go +++ b/pkg/replicas/replicas.go @@ -12,7 +12,6 @@ package replicas import ( "context" - "encoding/hex" "time" "github.com/ethersphere/bee/pkg/crypto" @@ -29,7 +28,6 @@ var ( RetryInterval = 300 * time.Millisecond privKey, _ = crypto.DecodeSecp256k1PrivateKey(append([]byte{1}, make([]byte, 31)...)) signer = crypto.NewDefaultSigner(privKey) - owner, _ = hex.DecodeString("dc5b20847f43d67928f49cd4f85d696b5a7617b5") ) // SetLevel sets the redundancy level in the context @@ -82,7 +80,7 @@ func (rr *replicator) replicate(i uint8) (sp *replica) { // calculate SOC address for potential replica h := swarm.NewHasher() _, _ = h.Write(id) - _, _ = h.Write(owner) + _, _ = h.Write(swarm.ReplicasOwner) return &replica{h.Sum(nil), id} } From 94c067f735dee8d8db909899721497c6d8e845a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Levente=20T=C3=B3th?= Date: Tue, 19 Dec 2023 17:00:26 +0100 Subject: [PATCH 4/6] test: joiner fix --- pkg/file/redundancy/getter/getter_test.go | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/pkg/file/redundancy/getter/getter_test.go b/pkg/file/redundancy/getter/getter_test.go index d19b5535057..d1c36d4e924 100644 --- a/pkg/file/redundancy/getter/getter_test.go +++ b/pkg/file/redundancy/getter/getter_test.go @@ -228,17 +228,6 @@ func testDecodingFallback(t *testing.T, s getter.Strategy, strict bool) { waitErased <- err }() - // set timeouts for the cases - var timeout time.Duration - switch { - case strict: - timeout = 2*getter.StrategyTimeout - 10*time.Millisecond - case s == getter.NONE: - timeout = 4*getter.StrategyTimeout - 10*time.Millisecond - case s == getter.DATA: - timeout = 3*getter.StrategyTimeout - 10*time.Millisecond - } - // wait for delayed chunk retrieval to complete select { case err := <-waitDelayed: @@ -297,7 +286,7 @@ func testDecodingFallback(t *testing.T, s getter.Strategy, strict bool) { t.Fatal("unexpected timeout using strategy", s, "with strict", strict) } } - case <-time.After(timeout): + case <-time.After(getter.StrategyTimeout * 3): if !strict || s != getter.NONE { t.Fatal("unexpected timeout using strategy", s, "with strict", strict) } From f5b13e52cf72049e3ae2687d1b5ec429d4220413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Levente=20T=C3=B3th?= Date: Tue, 19 Dec 2023 17:21:07 +0100 Subject: [PATCH 5/6] test: raise context timeout --- pkg/file/redundancy/getter/getter_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/file/redundancy/getter/getter_test.go b/pkg/file/redundancy/getter/getter_test.go index d1c36d4e924..bb00f7ddd02 100644 --- a/pkg/file/redundancy/getter/getter_test.go +++ b/pkg/file/redundancy/getter/getter_test.go @@ -151,7 +151,7 @@ func testDecodingRACE(t *testing.T, bufSize, shardCnt, erasureCnt int) { err := context.DeadlineExceeded select { case err = <-q: - case <-time.After(getter.StrategyTimeout * 4): + case <-time.After(getter.StrategyTimeout * 10): } switch { case erasureCnt > parityCnt: From c5485496e3f7e292d8cb21a2a17ff3f62c4b34a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Levente=20T=C3=B3th?= Date: Tue, 19 Dec 2023 17:22:21 +0100 Subject: [PATCH 6/6] docs: review --- pkg/swarm/swarm.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/swarm/swarm.go b/pkg/swarm/swarm.go index 94a7fe711e5..b69b4c034bf 100644 --- a/pkg/swarm/swarm.go +++ b/pkg/swarm/swarm.go @@ -38,7 +38,7 @@ var ( ) var ( - // Ethereum Address of the for Dispersed Replicas writes + // Ethereum Address for SOC owner of Dispersed Replicas // generated from private key 0x0100000000000000000000000000000000000000000000000000000000000000 ReplicasOwner, _ = hex.DecodeString("dc5b20847f43d67928f49cd4f85d696b5a7617b5") )