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  }