github.com/klaytn/klaytn@v1.12.1/consensus/istanbul/core/message_set.go (about) 1 // Modifications Copyright 2018 The klaytn Authors 2 // Copyright 2017 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from quorum/consensus/istanbul/core/message_set.go (2018/06/04). 19 // Modified and improved for the klaytn development. 20 21 package core 22 23 import ( 24 "fmt" 25 "math/big" 26 "strings" 27 "sync" 28 29 "github.com/klaytn/klaytn/common" 30 "github.com/klaytn/klaytn/consensus/istanbul" 31 ) 32 33 // Construct a new message set to accumulate messages for given sequence/view number. 34 func newMessageSet(valSet istanbul.ValidatorSet) *messageSet { 35 return &messageSet{ 36 view: &istanbul.View{ 37 Round: new(big.Int), 38 Sequence: new(big.Int), 39 }, 40 messagesMu: new(sync.Mutex), 41 messages: make(map[common.Address]*message), 42 valSet: valSet, 43 } 44 } 45 46 // ---------------------------------------------------------------------------- 47 48 type messageSet struct { 49 view *istanbul.View 50 valSet istanbul.ValidatorSet 51 messagesMu *sync.Mutex 52 messages map[common.Address]*message 53 } 54 55 func (ms *messageSet) View() *istanbul.View { 56 return ms.view 57 } 58 59 func (ms *messageSet) GetMessages() string { 60 ms.messagesMu.Lock() 61 defer ms.messagesMu.Unlock() 62 63 ret := "\n" 64 for k := range ms.messages { 65 ret = ret + "\t" + k.String() + "\n" 66 } 67 return ret 68 } 69 70 func (ms *messageSet) Add(msg *message) error { 71 ms.messagesMu.Lock() 72 defer ms.messagesMu.Unlock() 73 74 if err := ms.verify(msg); err != nil { 75 return err 76 } 77 78 return ms.addVerifiedMessage(msg) 79 } 80 81 func (ms *messageSet) Values() (result []*message) { 82 ms.messagesMu.Lock() 83 defer ms.messagesMu.Unlock() 84 85 for _, v := range ms.messages { 86 result = append(result, v) 87 } 88 89 return result 90 } 91 92 func (ms *messageSet) Size() int { 93 ms.messagesMu.Lock() 94 defer ms.messagesMu.Unlock() 95 return len(ms.messages) 96 } 97 98 func (ms *messageSet) Get(addr common.Address) *message { 99 ms.messagesMu.Lock() 100 defer ms.messagesMu.Unlock() 101 return ms.messages[addr] 102 } 103 104 // ---------------------------------------------------------------------------- 105 106 func (ms *messageSet) verify(msg *message) error { 107 // verify if the message comes from one of the validators 108 if _, v := ms.valSet.GetByAddress(msg.Address); v == nil { 109 return istanbul.ErrUnauthorizedAddress 110 } 111 112 // TODO: check view number and sequence number 113 114 return nil 115 } 116 117 func (ms *messageSet) addVerifiedMessage(msg *message) error { 118 ms.messages[msg.Address] = msg 119 return nil 120 } 121 122 func (ms *messageSet) String() string { 123 ms.messagesMu.Lock() 124 defer ms.messagesMu.Unlock() 125 addresses := make([]string, 0, len(ms.messages)) 126 for _, v := range ms.messages { 127 addresses = append(addresses, v.Address.String()) 128 } 129 return fmt.Sprintf("[%v]", strings.Join(addresses, ", ")) 130 }