github.com/status-im/status-go@v1.1.0/eth-node/types/topic.go (about) 1 package types 2 3 import ( 4 "github.com/ethereum/go-ethereum/common/hexutil" 5 ) 6 7 const ( 8 // TopicLength is the expected length of the topic, in bytes 9 TopicLength = 4 10 // BloomFilterSize is the expected length of a bloom filter byte array, in bytes 11 BloomFilterSize = 64 12 ) 13 14 // TopicType represents a cryptographically secure, probabilistic partial 15 // classifications of a message, determined as the first (left) 4 bytes of the 16 // SHA3 hash of some arbitrary data given by the original author of the message. 17 type TopicType [TopicLength]byte 18 19 // BytesToTopic converts from the byte array representation of a topic 20 // into the TopicType type. 21 func BytesToTopic(b []byte) (t TopicType) { 22 sz := TopicLength 23 if x := len(b); x < TopicLength { 24 sz = x 25 } 26 for i := 0; i < sz; i++ { 27 t[i] = b[i] 28 } 29 return t 30 } 31 32 // String converts a topic byte array to a string representation. 33 func (t TopicType) String() string { 34 return EncodeHex(t[:]) 35 } 36 37 // MarshalText returns the hex representation of t. 38 func (t TopicType) MarshalText() ([]byte, error) { 39 return HexBytes(t[:]).MarshalText() 40 } 41 42 // UnmarshalText parses a hex representation to a topic. 43 func (t *TopicType) UnmarshalText(input []byte) error { 44 return UnmarshalFixedText("Topic", input, t[:]) 45 } 46 47 // TopicToBloom converts the topic (4 bytes) to the bloom filter (64 bytes) 48 func TopicToBloom(topic TopicType) []byte { 49 b := make([]byte, BloomFilterSize) 50 var index [3]int 51 for j := 0; j < 3; j++ { 52 index[j] = int(topic[j]) 53 if (topic[3] & (1 << uint(j))) != 0 { 54 index[j] += 256 55 } 56 } 57 58 for j := 0; j < 3; j++ { 59 byteIndex := index[j] / 8 60 bitIndex := index[j] % 8 61 b[byteIndex] = (1 << uint(bitIndex)) 62 } 63 return b 64 } 65 66 // BloomFilterMatch returns true if a sample matches a bloom filter 67 func BloomFilterMatch(filter, sample []byte) bool { 68 if filter == nil { 69 return true 70 } 71 72 for i := 0; i < BloomFilterSize; i++ { 73 f := filter[i] 74 s := sample[i] 75 if (f | s) != f { 76 return false 77 } 78 } 79 80 return true 81 } 82 83 // MakeFullNodeBloom returns a bloom filter which matches all topics 84 func MakeFullNodeBloom() []byte { 85 bloom := make([]byte, BloomFilterSize) 86 for i := 0; i < BloomFilterSize; i++ { 87 bloom[i] = 0xFF 88 } 89 return bloom 90 } 91 92 func StringToTopic(s string) (t TopicType) { 93 str, _ := hexutil.Decode(s) 94 return BytesToTopic(str) 95 } 96 97 func TopicTypeToByteArray(t TopicType) []byte { 98 return t[:4] 99 }