github.com/ethersphere/bee/v2@v2.2.0/pkg/soc/validator_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 soc_test 6 7 import ( 8 "crypto/rand" 9 "io" 10 "strings" 11 "testing" 12 13 "github.com/ethersphere/bee/v2/pkg/cac" 14 "github.com/ethersphere/bee/v2/pkg/crypto" 15 "github.com/ethersphere/bee/v2/pkg/soc" 16 "github.com/ethersphere/bee/v2/pkg/swarm" 17 ) 18 19 // TestValid verifies that the validator can detect 20 // valid soc chunks. 21 func TestValid(t *testing.T) { 22 t.Parallel() 23 24 socAddress := swarm.MustParseHexAddress("9d453ebb73b2fedaaf44ceddcf7a0aa37f3e3d6453fea5841c31f0ea6d61dc85") 25 26 // signed soc chunk of: 27 // id: 0 28 // wrapped chunk of: `foo` 29 // owner: 0x8d3766440f0d7b949a5e32995d09619a7f86e632 30 sch := swarm.NewChunk(socAddress, []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 205, 56, 79, 235, 193, 51, 183, 178, 69, 229, 221, 198, 45, 130, 210, 205, 237, 145, 130, 210, 113, 97, 38, 205, 136, 68, 80, 154, 246, 90, 5, 61, 235, 65, 130, 8, 2, 127, 84, 142, 62, 136, 52, 58, 246, 248, 74, 135, 114, 251, 60, 235, 192, 161, 131, 58, 14, 167, 236, 12, 19, 72, 49, 27, 3, 0, 0, 0, 0, 0, 0, 0, 102, 111, 111}) 31 32 // check valid chunk 33 if !soc.Valid(sch) { 34 t.Fatal("valid chunk evaluates to invalid") 35 } 36 } 37 38 // TestValidDispersedReplica verifies that the validator can detect 39 // valid dispersed replicas chunks. 40 func TestValidDispersedReplica(t *testing.T) { 41 t.Parallel() 42 43 t.Run("valid", func(t *testing.T) { 44 privKey, _ := crypto.DecodeSecp256k1PrivateKey(append([]byte{1}, make([]byte, 31)...)) 45 signer := crypto.NewDefaultSigner(privKey) 46 47 chData := make([]byte, swarm.ChunkSize) 48 _, _ = io.ReadFull(rand.Reader, chData) 49 ch, err := cac.New(chData) 50 if err != nil { 51 t.Fatal(err) 52 } 53 id := append([]byte{1}, ch.Address().Bytes()[1:]...) 54 55 socCh, err := soc.New(id, ch).Sign(signer) 56 if err != nil { 57 t.Fatal(err) 58 } 59 60 // check valid chunk 61 if !soc.Valid(socCh) { 62 t.Fatal("dispersed replica chunk is invalid") 63 } 64 }) 65 66 t.Run("invalid", func(t *testing.T) { 67 privKey, _ := crypto.DecodeSecp256k1PrivateKey(append([]byte{1}, make([]byte, 31)...)) 68 signer := crypto.NewDefaultSigner(privKey) 69 70 chData := make([]byte, swarm.ChunkSize) 71 _, _ = io.ReadFull(rand.Reader, chData) 72 ch, err := cac.New(chData) 73 if err != nil { 74 t.Fatal(err) 75 } 76 id := append([]byte{1}, ch.Address().Bytes()[1:]...) 77 // change to invalid ID 78 id[2] += 1 79 80 socCh, err := soc.New(id, ch).Sign(signer) 81 if err != nil { 82 t.Fatal(err) 83 } 84 85 // check valid chunk 86 if soc.Valid(socCh) { 87 t.Fatal("dispersed replica should be invalid") 88 } 89 }) 90 } 91 92 // TestInvalid verifies that the validator can detect chunks 93 // with invalid data and invalid address. 94 func TestInvalid(t *testing.T) { 95 t.Parallel() 96 97 socAddress := swarm.MustParseHexAddress("9d453ebb73b2fedaaf44ceddcf7a0aa37f3e3d6453fea5841c31f0ea6d61dc85") 98 // signed soc chunk of: 99 // id: 0 100 // wrapped chunk of: `foo` 101 // owner: 0x8d3766440f0d7b949a5e32995d09619a7f86e632 102 103 makeSocData := func() []byte { 104 return []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 205, 56, 79, 235, 193, 51, 183, 178, 69, 229, 221, 198, 45, 130, 210, 205, 237, 145, 130, 210, 113, 97, 38, 205, 136, 68, 80, 154, 246, 90, 5, 61, 235, 65, 130, 8, 2, 127, 84, 142, 62, 136, 52, 58, 246, 248, 74, 135, 114, 251, 60, 235, 192, 161, 131, 58, 14, 167, 236, 12, 19, 72, 49, 27, 3, 0, 0, 0, 0, 0, 0, 0, 102, 111, 111} 105 } 106 107 for _, c := range []struct { 108 name string 109 chunk func() swarm.Chunk 110 }{ 111 { 112 name: "wrong soc address", 113 chunk: func() swarm.Chunk { 114 wrongAddressBytes := socAddress.Clone().Bytes() 115 wrongAddressBytes[0] = 255 - wrongAddressBytes[0] 116 wrongAddress := swarm.NewAddress(wrongAddressBytes) 117 data := makeSocData() 118 return swarm.NewChunk(wrongAddress, data) 119 }, 120 }, 121 { 122 name: "invalid data", 123 chunk: func() swarm.Chunk { 124 addr := socAddress.Clone() 125 data := makeSocData() 126 cursor := swarm.HashSize + swarm.SocSignatureSize 127 chunkData := data[cursor:] 128 chunkData[0] = 0x01 129 return swarm.NewChunk(addr, data) 130 }, 131 }, 132 { 133 name: "invalid id", 134 chunk: func() swarm.Chunk { 135 addr := socAddress.Clone() 136 data := makeSocData() 137 id := data[:swarm.HashSize] 138 id[0] = 0x01 139 return swarm.NewChunk(addr, data) 140 }, 141 }, 142 { 143 name: "invalid signature", 144 chunk: func() swarm.Chunk { 145 addr := socAddress.Clone() 146 data := makeSocData() 147 // modify signature 148 cursor := swarm.HashSize + swarm.SocSignatureSize 149 sig := data[swarm.HashSize:cursor] 150 sig[0] = 0x01 151 return swarm.NewChunk(addr, data) 152 }, 153 }, 154 { 155 name: "nil data", 156 chunk: func() swarm.Chunk { 157 addr := socAddress.Clone() 158 return swarm.NewChunk(addr, nil) 159 }, 160 }, 161 { 162 name: "small data", 163 chunk: func() swarm.Chunk { 164 addr := socAddress.Clone() 165 return swarm.NewChunk(addr, []byte("small")) 166 }, 167 }, 168 { 169 name: "large data", 170 chunk: func() swarm.Chunk { 171 addr := socAddress.Clone() 172 return swarm.NewChunk(addr, []byte(strings.Repeat("a", swarm.ChunkSize+swarm.SpanSize+1))) 173 }, 174 }, 175 } { 176 c := c 177 t.Run(c.name, func(t *testing.T) { 178 t.Parallel() 179 180 if soc.Valid(c.chunk()) { 181 t.Fatal("chunk with invalid data evaluates to valid") 182 } 183 }) 184 } 185 }