github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/network/payload/extensible.go (about) 1 package payload 2 3 import ( 4 "errors" 5 6 "github.com/nspcc-dev/neo-go/pkg/core/transaction" 7 "github.com/nspcc-dev/neo-go/pkg/crypto/hash" 8 "github.com/nspcc-dev/neo-go/pkg/io" 9 "github.com/nspcc-dev/neo-go/pkg/util" 10 ) 11 12 const maxExtensibleCategorySize = 32 13 14 // ConsensusCategory is a message category for consensus-related extensible 15 // payloads. 16 const ConsensusCategory = "dBFT" 17 18 // Extensible represents a payload containing arbitrary data. 19 type Extensible struct { 20 // Category is the payload type. 21 Category string 22 // ValidBlockStart is the starting height for a payload to be valid. 23 ValidBlockStart uint32 24 // ValidBlockEnd is the height after which a payload becomes invalid. 25 ValidBlockEnd uint32 26 // Sender is the payload sender or signer. 27 Sender util.Uint160 28 // Data is custom payload data. 29 Data []byte 30 // Witness is payload witness. 31 Witness transaction.Witness 32 33 hash util.Uint256 34 } 35 36 var errInvalidPadding = errors.New("invalid padding") 37 38 // NewExtensible creates a new extensible payload. 39 func NewExtensible() *Extensible { 40 return &Extensible{} 41 } 42 43 func (e *Extensible) encodeBinaryUnsigned(w *io.BinWriter) { 44 w.WriteString(e.Category) 45 w.WriteU32LE(e.ValidBlockStart) 46 w.WriteU32LE(e.ValidBlockEnd) 47 w.WriteBytes(e.Sender[:]) 48 w.WriteVarBytes(e.Data) 49 } 50 51 // EncodeBinary implements io.Serializable. 52 func (e *Extensible) EncodeBinary(w *io.BinWriter) { 53 e.encodeBinaryUnsigned(w) 54 w.WriteB(1) 55 e.Witness.EncodeBinary(w) 56 } 57 58 func (e *Extensible) decodeBinaryUnsigned(r *io.BinReader) { 59 e.Category = r.ReadString(maxExtensibleCategorySize) 60 e.ValidBlockStart = r.ReadU32LE() 61 e.ValidBlockEnd = r.ReadU32LE() 62 r.ReadBytes(e.Sender[:]) 63 e.Data = r.ReadVarBytes(MaxSize) 64 } 65 66 // DecodeBinary implements io.Serializable. 67 func (e *Extensible) DecodeBinary(r *io.BinReader) { 68 e.decodeBinaryUnsigned(r) 69 if r.ReadB() != 1 { 70 if r.Err != nil { 71 return 72 } 73 r.Err = errInvalidPadding 74 return 75 } 76 e.Witness.DecodeBinary(r) 77 } 78 79 // Hash returns payload hash. 80 func (e *Extensible) Hash() util.Uint256 { 81 if e.hash.Equals(util.Uint256{}) { 82 e.createHash() 83 } 84 return e.hash 85 } 86 87 // createHash creates hashes of the payload. 88 func (e *Extensible) createHash() { 89 buf := io.NewBufBinWriter() 90 e.encodeBinaryUnsigned(buf.BinWriter) 91 e.hash = hash.Sha256(buf.Bytes()) 92 }