github.com/coltonfike/e2c@v21.1.0+incompatible/core/types/istanbul.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 types 18 19 import ( 20 "errors" 21 "io" 22 23 "github.com/ethereum/go-ethereum/common" 24 "github.com/ethereum/go-ethereum/rlp" 25 ) 26 27 var ( 28 // IstanbulDigest represents a hash of "Istanbul practical byzantine fault tolerance" 29 // to identify whether the block is from Istanbul consensus engine 30 IstanbulDigest = common.HexToHash("0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365") 31 32 IstanbulExtraVanity = 32 // Fixed number of extra-data bytes reserved for validator vanity 33 IstanbulExtraSeal = 65 // Fixed number of extra-data bytes reserved for validator seal 34 35 // ErrInvalidIstanbulHeaderExtra is returned if the length of extra-data is less than 32 bytes 36 ErrInvalidIstanbulHeaderExtra = errors.New("invalid istanbul header extra-data") 37 ) 38 39 type IstanbulExtra struct { 40 Validators []common.Address 41 Seal []byte 42 CommittedSeal [][]byte 43 } 44 45 // EncodeRLP serializes ist into the Ethereum RLP format. 46 func (ist *IstanbulExtra) EncodeRLP(w io.Writer) error { 47 return rlp.Encode(w, []interface{}{ 48 ist.Validators, 49 ist.Seal, 50 ist.CommittedSeal, 51 }) 52 } 53 54 // DecodeRLP implements rlp.Decoder, and load the istanbul fields from a RLP stream. 55 func (ist *IstanbulExtra) DecodeRLP(s *rlp.Stream) error { 56 var istanbulExtra struct { 57 Validators []common.Address 58 Seal []byte 59 CommittedSeal [][]byte 60 } 61 if err := s.Decode(&istanbulExtra); err != nil { 62 return err 63 } 64 ist.Validators, ist.Seal, ist.CommittedSeal = istanbulExtra.Validators, istanbulExtra.Seal, istanbulExtra.CommittedSeal 65 return nil 66 } 67 68 // ExtractIstanbulExtra extracts all values of the IstanbulExtra from the header. It returns an 69 // error if the length of the given extra-data is less than 32 bytes or the extra-data can not 70 // be decoded. 71 func ExtractIstanbulExtra(h *Header) (*IstanbulExtra, error) { 72 if len(h.Extra) < IstanbulExtraVanity { 73 return nil, ErrInvalidIstanbulHeaderExtra 74 } 75 76 var istanbulExtra *IstanbulExtra 77 err := rlp.DecodeBytes(h.Extra[IstanbulExtraVanity:], &istanbulExtra) 78 if err != nil { 79 return nil, err 80 } 81 return istanbulExtra, nil 82 } 83 84 // IstanbulFilteredHeader returns a filtered header which some information (like seal, committed seals) 85 // are clean to fulfill the Istanbul hash rules. It returns nil if the extra-data cannot be 86 // decoded/encoded by rlp. 87 func IstanbulFilteredHeader(h *Header, keepSeal bool) *Header { 88 newHeader := CopyHeader(h) 89 istanbulExtra, err := ExtractIstanbulExtra(newHeader) 90 if err != nil { 91 return nil 92 } 93 94 if !keepSeal { 95 istanbulExtra.Seal = []byte{} 96 } 97 istanbulExtra.CommittedSeal = [][]byte{} 98 99 payload, err := rlp.EncodeToBytes(&istanbulExtra) 100 if err != nil { 101 return nil 102 } 103 104 newHeader.Extra = append(newHeader.Extra[:IstanbulExtraVanity], payload...) 105 106 return newHeader 107 }