github.com/kisexp/xdchain@v0.0.0-20211206025815-490d6b732aa7/consensus/istanbul/ibft/types/message.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 ibfttypes 18 19 import ( 20 "bytes" 21 "fmt" 22 "io" 23 24 "github.com/kisexp/xdchain/common" 25 istanbulcommon "github.com/kisexp/xdchain/consensus/istanbul/common" 26 "github.com/kisexp/xdchain/rlp" 27 ) 28 29 const ( 30 MsgPreprepare uint64 = iota 31 MsgPrepare 32 MsgCommit 33 MsgRoundChange 34 // msgAll 35 ) 36 37 type Message struct { 38 Code uint64 39 Msg []byte 40 Address common.Address 41 Signature []byte 42 CommittedSeal []byte 43 } 44 45 // ============================================== 46 // 47 // define the functions that needs to be provided for rlp Encoder/Decoder. 48 49 // EncodeRLP serializes m into the Ethereum RLP format. 50 func (m *Message) EncodeRLP(w io.Writer) error { 51 return rlp.Encode(w, []interface{}{m.Code, m.Msg, m.Address, m.Signature, m.CommittedSeal}) 52 } 53 54 // DecodeRLP implements rlp.Decoder, and load the consensus fields from a RLP stream. 55 func (m *Message) DecodeRLP(s *rlp.Stream) error { 56 var msg struct { 57 Code uint64 58 Msg []byte 59 Address common.Address 60 Signature []byte 61 CommittedSeal []byte 62 } 63 64 if err := s.Decode(&msg); err != nil { 65 return err 66 } 67 m.Code, m.Msg, m.Address, m.Signature, m.CommittedSeal = msg.Code, msg.Msg, msg.Address, msg.Signature, msg.CommittedSeal 68 return nil 69 } 70 71 // ============================================== 72 // 73 // define the functions that needs to be provided for core. 74 75 func (m *Message) FromPayload(b []byte, validateFn func([]byte, []byte) (common.Address, error)) error { 76 // Decode message 77 err := rlp.DecodeBytes(b, &m) 78 if err != nil { 79 return err 80 } 81 82 // Validate message (on a message without Signature) 83 if validateFn != nil { 84 var payload []byte 85 payload, err = m.PayloadNoSig() 86 if err != nil { 87 return err 88 } 89 90 signerAdd, err := validateFn(payload, m.Signature) 91 if err != nil { 92 return err 93 } 94 if !bytes.Equal(signerAdd.Bytes(), m.Address.Bytes()) { 95 return istanbulcommon.ErrInvalidSigner 96 } 97 } 98 return nil 99 } 100 101 func (m *Message) Payload() ([]byte, error) { 102 return rlp.EncodeToBytes(m) 103 } 104 105 func (m *Message) PayloadNoSig() ([]byte, error) { 106 return rlp.EncodeToBytes(&Message{ 107 Code: m.Code, 108 Msg: m.Msg, 109 Address: m.Address, 110 Signature: []byte{}, 111 CommittedSeal: m.CommittedSeal, 112 }) 113 } 114 115 func (m *Message) Decode(val interface{}) error { 116 return rlp.DecodeBytes(m.Msg, val) 117 } 118 119 func (m *Message) String() string { 120 return fmt.Sprintf("{Code: %v, Address: %v}", m.Code, m.Address.String()) 121 } 122 123 // ============================================== 124 // 125 // helper functions 126 127 func Encode(val interface{}) ([]byte, error) { 128 return rlp.EncodeToBytes(val) 129 }