github.com/Blockdaemon/celo-blockchain@v0.0.0-20200129231733-e667f6b08419/consensus/istanbul/core/message_set.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package core 18 19 import ( 20 "fmt" 21 "io" 22 "strings" 23 "sync" 24 25 "github.com/ethereum/go-ethereum/consensus/istanbul/validator" 26 27 "github.com/ethereum/go-ethereum/common" 28 "github.com/ethereum/go-ethereum/consensus/istanbul" 29 "github.com/ethereum/go-ethereum/rlp" 30 ) 31 32 type MessageSet interface { 33 fmt.Stringer 34 Add(msg *istanbul.Message) error 35 GetAddressIndex(addr common.Address) (uint64, error) 36 Remove(address common.Address) 37 Values() (result []*istanbul.Message) 38 Size() int 39 Get(addr common.Address) *istanbul.Message 40 Addresses() []common.Address 41 Serialize() ([]byte, error) 42 } 43 44 type messageSetImpl struct { 45 valSet istanbul.ValidatorSet 46 messagesMu *sync.Mutex 47 messages map[common.Address]*istanbul.Message 48 } 49 50 // Construct a new message set to accumulate messages for given sequence/view number. 51 func newMessageSet(valSet istanbul.ValidatorSet) MessageSet { 52 return &messageSetImpl{ 53 messagesMu: new(sync.Mutex), 54 messages: make(map[common.Address]*istanbul.Message), 55 valSet: valSet, 56 } 57 } 58 59 func deserializeMessageSet(binaryData []byte) (MessageSet, error) { 60 var ms messageSetImpl 61 62 err := rlp.DecodeBytes(binaryData, &ms) 63 if err != nil { 64 return nil, err 65 } 66 return &ms, nil 67 } 68 69 // ---------------------------------------------------------------------------- 70 71 func (ms *messageSetImpl) Add(msg *istanbul.Message) error { 72 ms.messagesMu.Lock() 73 defer ms.messagesMu.Unlock() 74 75 if !ms.valSet.ContainsByAddress(msg.Address) { 76 return istanbul.ErrUnauthorizedAddress 77 } 78 ms.messages[msg.Address] = msg 79 80 return nil 81 } 82 83 func (ms *messageSetImpl) GetAddressIndex(addr common.Address) (uint64, error) { 84 ms.messagesMu.Lock() 85 defer ms.messagesMu.Unlock() 86 87 i := ms.valSet.GetIndex(addr) 88 if i == -1 { 89 return 0, istanbul.ErrUnauthorizedAddress 90 } 91 92 return uint64(i), nil 93 } 94 95 func (ms *messageSetImpl) Remove(address common.Address) { 96 ms.messagesMu.Lock() 97 defer ms.messagesMu.Unlock() 98 99 delete(ms.messages, address) 100 } 101 102 func (ms *messageSetImpl) Values() (result []*istanbul.Message) { 103 ms.messagesMu.Lock() 104 defer ms.messagesMu.Unlock() 105 106 for _, v := range ms.messages { 107 result = append(result, v) 108 } 109 110 return result 111 } 112 113 func (ms *messageSetImpl) Size() int { 114 ms.messagesMu.Lock() 115 defer ms.messagesMu.Unlock() 116 return len(ms.messages) 117 } 118 119 func (ms *messageSetImpl) Get(addr common.Address) *istanbul.Message { 120 ms.messagesMu.Lock() 121 defer ms.messagesMu.Unlock() 122 return ms.messages[addr] 123 } 124 125 func (ms *messageSetImpl) Addresses() []common.Address { 126 ms.messagesMu.Lock() 127 defer ms.messagesMu.Unlock() 128 returnList := make([]common.Address, len(ms.messages)) 129 130 i := 0 131 for addr := range ms.messages { 132 returnList[i] = addr 133 i++ 134 } 135 136 return returnList 137 } 138 139 func (ms *messageSetImpl) String() string { 140 ms.messagesMu.Lock() 141 defer ms.messagesMu.Unlock() 142 addresses := make([]string, 0, len(ms.messages)) 143 for _, v := range ms.messages { 144 addresses = append(addresses, v.Address.String()) 145 } 146 return fmt.Sprintf("[<%v> %v]", len(ms.messages), strings.Join(addresses, ", ")) 147 } 148 149 func (s *messageSetImpl) Serialize() ([]byte, error) { 150 return rlp.EncodeToBytes(s) 151 } 152 153 // RLP Encoding ----------------------------------------------------------------------- 154 155 // EncodeRLP impl 156 func (s *messageSetImpl) EncodeRLP(w io.Writer) error { 157 serializedValSet, err := s.valSet.Serialize() 158 if err != nil { 159 return err 160 } 161 162 messageKeys := make([]common.Address, len(s.messages)) 163 messageValues := make([]*istanbul.Message, len(s.messages)) 164 165 i := 0 166 for k, v := range s.messages { 167 messageKeys[i] = k 168 messageValues[i] = v 169 i++ 170 } 171 172 return rlp.Encode(w, []interface{}{ 173 serializedValSet, 174 messageKeys, 175 messageValues, 176 }) 177 } 178 179 // DecodeRLP Impl 180 func (s *messageSetImpl) DecodeRLP(stream *rlp.Stream) error { 181 var data struct { 182 SerializedValSet []byte 183 MessageKeys []common.Address 184 MessageValues []*istanbul.Message 185 } 186 187 err := stream.Decode(&data) 188 if err != nil { 189 return err 190 } 191 192 valSet, err := validator.DeserializeValidatorSet(data.SerializedValSet) 193 if err != nil { 194 return err 195 } 196 197 messages := make(map[common.Address]*istanbul.Message) 198 for i, addr := range data.MessageKeys { 199 messages[addr] = data.MessageValues[i] 200 } 201 202 *s = messageSetImpl{ 203 valSet: valSet, 204 messages: messages, 205 messagesMu: new(sync.Mutex), 206 } 207 208 return nil 209 }