github.com/ethersphere/bee/v2@v2.2.0/pkg/swarm/swarm.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 swarm contains most basic and general Swarm concepts. 6 package swarm 7 8 import ( 9 "bytes" 10 "encoding" 11 "encoding/hex" 12 "encoding/json" 13 "errors" 14 "fmt" 15 ) 16 17 const ( 18 StampIndexSize = 8 // TODO: use this size in related code. 19 StampTimestampSize = 8 // TODO: use this size in related code. 20 SpanSize = 8 21 SectionSize = 32 22 Branches = 128 23 EncryptedBranches = Branches / 2 24 BmtBranches = 128 25 ChunkSize = SectionSize * Branches 26 HashSize = 32 27 MaxPO uint8 = 31 28 ExtendedPO uint8 = MaxPO + 5 29 MaxBins = MaxPO + 1 30 ChunkWithSpanSize = ChunkSize + SpanSize 31 SocSignatureSize = 65 32 SocMinChunkSize = HashSize + SocSignatureSize + SpanSize 33 SocMaxChunkSize = SocMinChunkSize + ChunkSize 34 ) 35 36 var ( 37 ErrInvalidChunk = errors.New("invalid chunk") 38 ) 39 40 var ( 41 // Ethereum Address for SOC owner of Dispersed Replicas 42 // generated from private key 0x0100000000000000000000000000000000000000000000000000000000000000 43 ReplicasOwner, _ = hex.DecodeString("dc5b20847f43d67928f49cd4f85d696b5a7617b5") 44 ) 45 46 var ( 47 // EmptyAddress is the address that is all zeroes. 48 EmptyAddress = NewAddress(make([]byte, HashSize)) 49 // ZeroAddress is the address that has no value. 50 ZeroAddress = NewAddress(nil) 51 ) 52 53 // Address represents an address in Swarm metric space of 54 // Node and Chunk addresses. 55 type Address struct { 56 b []byte 57 } 58 59 // NewAddress constructs Address from a byte slice. 60 func NewAddress(b []byte) Address { 61 return Address{b: b} 62 } 63 64 // ParseHexAddress returns an Address from a hex-encoded string representation. 65 func ParseHexAddress(s string) (a Address, err error) { 66 b, err := hex.DecodeString(s) 67 if err != nil { 68 return a, err 69 } 70 return NewAddress(b), nil 71 } 72 73 // MustParseHexAddress returns an Address from a hex-encoded string 74 // representation, and panics if there is a parse error. 75 func MustParseHexAddress(s string) Address { 76 a, err := ParseHexAddress(s) 77 if err != nil { 78 panic(err) 79 } 80 return a 81 } 82 83 // String returns a hex-encoded representation of the Address. 84 func (a Address) String() string { 85 return hex.EncodeToString(a.b) 86 } 87 88 // Equal returns true if two addresses are identical. 89 func (a Address) Equal(b Address) bool { 90 return bytes.Equal(a.b, b.b) 91 } 92 93 // MemberOf returns true if the address is a member of the 94 // provided set. 95 func (a Address) MemberOf(addrs []Address) bool { 96 return ContainsAddress(addrs, a) 97 } 98 99 // IsZero returns true if the Address is not set to any value. 100 func (a Address) IsZero() bool { 101 return a.Equal(ZeroAddress) 102 } 103 104 // IsEmpty returns true if the Address is all zeroes. 105 func (a Address) IsEmpty() bool { 106 return a.Equal(EmptyAddress) 107 } 108 109 // IsValidLength returns true if the Address is of valid length. 110 func (a Address) IsValidLength() bool { 111 return len(a.b) == HashSize 112 } 113 114 // IsValidNonEmpty returns true if the Address has valid length and is not empty. 115 func (a Address) IsValidNonEmpty() bool { 116 return a.IsValidLength() && !a.IsEmpty() 117 } 118 119 // Bytes returns bytes representation of the Address. 120 func (a Address) Bytes() []byte { 121 return a.b 122 } 123 124 // ByteString returns raw Address string without encoding. 125 func (a Address) ByteString() string { 126 return string(a.Bytes()) 127 } 128 129 // UnmarshalJSON sets Address to a value from JSON-encoded representation. 130 func (a *Address) UnmarshalJSON(b []byte) (err error) { 131 var s string 132 if err := json.Unmarshal(b, &s); err != nil { 133 return err 134 } 135 *a, err = ParseHexAddress(s) 136 return err 137 } 138 139 // MarshalJSON returns JSON-encoded representation of Address. 140 func (a Address) MarshalJSON() ([]byte, error) { 141 return json.Marshal(a.String()) 142 } 143 144 // Closer returns if x is closer to a than y 145 func (x Address) Closer(a Address, y Address) (bool, error) { 146 cmp, err := DistanceCmp(a, x, y) 147 return cmp == 1, err 148 } 149 150 // Clone returns a new swarm address which is a copy of this one. 151 func (a Address) Clone() Address { 152 if a.b == nil { 153 return Address{} 154 } 155 return Address{b: append(make([]byte, 0, len(a.b)), a.Bytes()...)} 156 } 157 158 // Compare returns an integer comparing two addresses lexicographically. 159 // The result will be 0 if a == b, -1 if a < b, and +1 if a > b. 160 func (a Address) Compare(b Address) int { 161 return bytes.Compare(a.b, b.b) 162 } 163 164 // AddressIterFunc is a callback on every address that is found by the iterator. 165 type AddressIterFunc func(address Address) error 166 167 type Chunk interface { 168 // Address returns the chunk address. 169 Address() Address 170 // Data returns the chunk data. 171 Data() []byte 172 // TagID returns the tag ID for this chunk. 173 TagID() uint32 174 // WithTagID attaches the tag ID to the chunk. 175 WithTagID(t uint32) Chunk 176 // Stamp returns the postage stamp associated with this chunk. 177 Stamp() Stamp 178 // WithStamp attaches a postage stamp to the chunk. 179 WithStamp(Stamp) Chunk 180 // Depth returns the batch depth of the stamp - allowed batch size = 2^{depth}. 181 Depth() uint8 182 // BucketDepth returns the bucket depth of the batch of the stamp - always < depth. 183 BucketDepth() uint8 184 // Immutable returns whether the batch is immutable 185 Immutable() bool 186 // WithBatch attaches batch parameters to the chunk. 187 WithBatch(depth, bucketDepth uint8, immutable bool) Chunk 188 // Equal checks if the chunk is equal to another. 189 Equal(Chunk) bool 190 } 191 192 // ChunkType indicates different categories of chunks. 193 type ChunkType uint8 194 195 // String implements Stringer interface. 196 func (ct ChunkType) String() string { 197 switch ct { 198 case ChunkTypeContentAddressed: 199 return "CAC" 200 case ChunkTypeSingleOwner: 201 return "SOC" 202 default: 203 return "unspecified" 204 } 205 } 206 207 // DO NOT CHANGE ORDER 208 const ( 209 ChunkTypeUnspecified ChunkType = iota 210 ChunkTypeContentAddressed 211 ChunkTypeSingleOwner 212 ) 213 214 // Stamp interface for postage.Stamp to avoid circular dependency 215 type Stamp interface { 216 BatchID() []byte 217 Index() []byte 218 Sig() []byte 219 Timestamp() []byte 220 Clone() Stamp 221 Hash() ([]byte, error) 222 encoding.BinaryMarshaler 223 encoding.BinaryUnmarshaler 224 } 225 226 type chunk struct { 227 addr Address 228 sdata []byte 229 tagID uint32 230 stamp Stamp 231 depth uint8 232 bucketDepth uint8 233 immutable bool 234 } 235 236 func NewChunk(addr Address, data []byte) Chunk { 237 return &chunk{ 238 addr: addr, 239 sdata: data, 240 } 241 } 242 243 func (c *chunk) WithTagID(t uint32) Chunk { 244 c.tagID = t 245 return c 246 } 247 248 func (c *chunk) WithStamp(stamp Stamp) Chunk { 249 c.stamp = stamp 250 return c 251 } 252 253 func (c *chunk) WithBatch(depth, bucketDepth uint8, immutable bool) Chunk { 254 c.depth = depth 255 c.bucketDepth = bucketDepth 256 c.immutable = immutable 257 return c 258 } 259 260 func (c *chunk) Address() Address { 261 return c.addr 262 } 263 264 func (c *chunk) Data() []byte { 265 return c.sdata 266 } 267 268 func (c *chunk) TagID() uint32 { 269 return c.tagID 270 } 271 272 func (c *chunk) Stamp() Stamp { 273 return c.stamp 274 } 275 276 func (c *chunk) Depth() uint8 { 277 return c.depth 278 } 279 280 func (c *chunk) BucketDepth() uint8 { 281 return c.bucketDepth 282 } 283 284 func (c *chunk) Immutable() bool { 285 return c.immutable 286 } 287 288 func (c *chunk) String() string { 289 return fmt.Sprintf("Address: %v Chunksize: %v", c.addr.String(), len(c.sdata)) 290 } 291 292 func (c *chunk) Equal(cp Chunk) bool { 293 return c.Address().Equal(cp.Address()) && bytes.Equal(c.Data(), cp.Data()) 294 } 295 296 var errBadCharacter = errors.New("bad character in binary address") 297 298 // ParseBitStrAddress parses overlay addresses in binary format (eg: 111101101) to it's corresponding overlay address. 299 func ParseBitStrAddress(src string) (Address, error) { 300 301 bitPos := 7 302 b := uint8(0) 303 304 var a []byte 305 306 for _, s := range src { 307 if s == '1' { 308 b |= 1 << bitPos 309 } else if s != '0' { 310 return ZeroAddress, errBadCharacter 311 } 312 bitPos-- 313 if bitPos < 0 { 314 a = append(a, b) 315 b = 0 316 bitPos = 7 317 } 318 } 319 320 a = append(a, b) 321 322 return bytesToAddr(a), nil 323 } 324 325 func bytesToAddr(b []byte) Address { 326 addr := make([]byte, HashSize) 327 copy(addr, b) 328 return NewAddress(addr) 329 }