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  }