github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/native/event_serializer.go (about) 1 package native 2 3 import ( 4 "errors" 5 "io" 6 7 "github.com/unicornultrafoundation/go-helios/hash" 8 "github.com/unicornultrafoundation/go-helios/native/dag" 9 "github.com/unicornultrafoundation/go-helios/native/idx" 10 "github.com/unicornultrafoundation/go-u2u/common/hexutil" 11 "github.com/unicornultrafoundation/go-u2u/core/types" 12 "github.com/unicornultrafoundation/go-u2u/rlp" 13 14 "github.com/unicornultrafoundation/go-u2u/utils/cser" 15 ) 16 17 var ( 18 ErrSerMalformedEvent = errors.New("serialization of malformed event") 19 ErrTooLowEpoch = errors.New("serialization of events with epoch<256 and version=0 is unsupported") 20 ErrUnknownVersion = errors.New("unknown serialization version") 21 ) 22 23 const MaxSerializationVersion = 1 24 25 const ProtocolMaxMsgSize = 10 * 1024 * 1024 26 27 func (e *Event) MarshalCSER(w *cser.Writer) error { 28 // version 29 if e.Version() > 0 { 30 w.BitsW.Write(2, 0) 31 w.U8(e.Version()) 32 } else { 33 if e.Epoch() < 256 { 34 return ErrTooLowEpoch 35 } 36 } 37 // base fields 38 if e.Version() > 0 { 39 w.U16(e.NetForkID()) 40 } 41 w.U32(uint32(e.Epoch())) 42 w.U32(uint32(e.Lamport())) 43 w.U32(uint32(e.Creator())) 44 w.U32(uint32(e.Seq())) 45 w.U32(uint32(e.Frame())) 46 w.U64(uint64(e.creationTime)) 47 medianTimeDiff := int64(e.creationTime) - int64(e.medianTime) 48 w.I64(medianTimeDiff) 49 // gas power 50 w.U64(e.gasPowerUsed) 51 w.U64(e.gasPowerLeft.Gas[0]) 52 w.U64(e.gasPowerLeft.Gas[1]) 53 // parents 54 w.U32(uint32(len(e.Parents()))) 55 for _, p := range e.Parents() { 56 if e.Lamport() < p.Lamport() { 57 return ErrSerMalformedEvent 58 } 59 // lamport difference 60 w.U32(uint32(e.Lamport() - p.Lamport())) 61 // without epoch and lamport 62 w.FixedBytes(p.Bytes()[8:]) 63 } 64 // prev epoch hash 65 w.Bool(e.prevEpochHash != nil) 66 if e.prevEpochHash != nil { 67 w.FixedBytes(e.prevEpochHash.Bytes()) 68 } 69 // tx hash 70 w.Bool(e.AnyTxs()) 71 if e.Version() > 0 { 72 w.Bool(e.AnyMisbehaviourProofs()) 73 w.Bool(e.AnyEpochVote()) 74 w.Bool(e.AnyBlockVotes()) 75 } 76 if e.AnyTxs() || e.AnyMisbehaviourProofs() || e.AnyBlockVotes() || e.AnyEpochVote() { 77 w.FixedBytes(e.PayloadHash().Bytes()) 78 } 79 // extra 80 w.SliceBytes(e.Extra()) 81 return nil 82 } 83 84 // MarshalBinary implements encoding.BinaryMarshaller interface. 85 func (e *Event) MarshalBinary() ([]byte, error) { 86 return cser.MarshalBinaryAdapter(e.MarshalCSER) 87 } 88 89 func eventUnmarshalCSER(r *cser.Reader, e *MutableEventPayload) (err error) { 90 // version 91 var version uint8 92 if r.BitsR.View(2) == 0 { 93 r.BitsR.Read(2) 94 version = r.U8() 95 if version == 0 { 96 return cser.ErrNonCanonicalEncoding 97 } 98 } 99 if version > MaxSerializationVersion { 100 return ErrUnknownVersion 101 } 102 103 // base fields 104 var netForkID uint16 105 if version > 0 { 106 netForkID = r.U16() 107 } 108 epoch := r.U32() 109 lamport := r.U32() 110 creator := r.U32() 111 seq := r.U32() 112 frame := r.U32() 113 creationTime := r.U64() 114 medianTimeDiff := r.I64() 115 // gas power 116 gasPowerUsed := r.U64() 117 gasPowerLeft0 := r.U64() 118 gasPowerLeft1 := r.U64() 119 // parents 120 parentsNum := r.U32() 121 if parentsNum > ProtocolMaxMsgSize/24 { 122 return cser.ErrTooLargeAlloc 123 } 124 parents := make(hash.Events, 0, parentsNum) 125 for i := uint32(0); i < parentsNum; i++ { 126 // lamport difference 127 lamportDiff := r.U32() 128 // hash 129 h := [24]byte{} 130 r.FixedBytes(h[:]) 131 eID := dag.MutableBaseEvent{} 132 eID.SetEpoch(idx.Epoch(epoch)) 133 eID.SetLamport(idx.Lamport(lamport - lamportDiff)) 134 eID.SetID(h) 135 parents.Add(eID.ID()) 136 } 137 // prev epoch hash 138 var prevEpochHash *hash.Hash 139 prevEpochHashExists := r.Bool() 140 if prevEpochHashExists { 141 prevEpochHash_ := hash.Hash{} 142 r.FixedBytes(prevEpochHash_[:]) 143 prevEpochHash = &prevEpochHash_ 144 } 145 // tx hash 146 anyTxs := r.Bool() 147 anyMisbehaviourProofs := version > 0 && r.Bool() 148 anyEpochVote := version > 0 && r.Bool() 149 anyBlockVotes := version > 0 && r.Bool() 150 payloadHash := EmptyPayloadHash(version) 151 if anyTxs || anyMisbehaviourProofs || anyEpochVote || anyBlockVotes { 152 r.FixedBytes(payloadHash[:]) 153 if payloadHash == EmptyPayloadHash(version) { 154 return cser.ErrNonCanonicalEncoding 155 } 156 } 157 // extra 158 extra := r.SliceBytes(ProtocolMaxMsgSize) 159 160 if version == 0 && epoch < 256 { 161 return ErrTooLowEpoch 162 } 163 164 e.SetVersion(version) 165 e.SetNetForkID(netForkID) 166 e.SetEpoch(idx.Epoch(epoch)) 167 e.SetLamport(idx.Lamport(lamport)) 168 e.SetCreator(idx.ValidatorID(creator)) 169 e.SetSeq(idx.Event(seq)) 170 e.SetFrame(idx.Frame(frame)) 171 e.SetCreationTime(Timestamp(creationTime)) 172 e.SetMedianTime(Timestamp(int64(creationTime) - medianTimeDiff)) 173 e.SetGasPowerUsed(gasPowerUsed) 174 e.SetGasPowerLeft(GasPowerLeft{[2]uint64{gasPowerLeft0, gasPowerLeft1}}) 175 e.SetParents(parents) 176 e.SetPrevEpochHash(prevEpochHash) 177 e.anyTxs = anyTxs 178 e.anyBlockVotes = anyBlockVotes 179 e.anyEpochVote = anyEpochVote 180 e.anyMisbehaviourProofs = anyMisbehaviourProofs 181 e.SetPayloadHash(payloadHash) 182 e.SetExtra(extra) 183 return nil 184 } 185 186 func MarshalTxsCSER(txs types.Transactions, w *cser.Writer) error { 187 // txs size 188 w.U56(uint64(txs.Len())) 189 // txs 190 for _, tx := range txs { 191 err := TransactionMarshalCSER(w, tx) 192 if err != nil { 193 return err 194 } 195 } 196 return nil 197 } 198 199 func (bvs LlrBlockVotes) MarshalCSER(w *cser.Writer) error { 200 w.U64(uint64(bvs.Start)) 201 w.U32(uint32(bvs.Epoch)) 202 w.U32(uint32(len(bvs.Votes))) 203 for _, r := range bvs.Votes { 204 w.FixedBytes(r[:]) 205 } 206 return nil 207 } 208 209 func (bvs *LlrBlockVotes) UnmarshalCSER(r *cser.Reader) error { 210 start := r.U64() 211 epoch := r.U32() 212 num := r.U32() 213 if num > ProtocolMaxMsgSize/32 { 214 return cser.ErrTooLargeAlloc 215 } 216 records := make([]hash.Hash, num) 217 for i := range records { 218 r.FixedBytes(records[i][:]) 219 } 220 bvs.Start = idx.Block(start) 221 bvs.Epoch = idx.Epoch(epoch) 222 bvs.Votes = records 223 return nil 224 } 225 226 func (ers LlrEpochVote) MarshalCSER(w *cser.Writer) error { 227 w.U32(uint32(ers.Epoch)) 228 w.FixedBytes(ers.Vote[:]) 229 return nil 230 } 231 232 func (ers *LlrEpochVote) UnmarshalCSER(r *cser.Reader) error { 233 epoch := r.U32() 234 record := hash.Hash{} 235 r.FixedBytes(record[:]) 236 ers.Epoch = idx.Epoch(epoch) 237 ers.Vote = record 238 return nil 239 } 240 241 func (e *EventPayload) MarshalCSER(w *cser.Writer) error { 242 if e.AnyTxs() != (e.txs.Len() != 0) { 243 return ErrSerMalformedEvent 244 } 245 if e.AnyMisbehaviourProofs() != (len(e.misbehaviourProofs) != 0) { 246 return ErrSerMalformedEvent 247 } 248 if e.AnyEpochVote() != (e.epochVote.Epoch != 0) { 249 return ErrSerMalformedEvent 250 } 251 if e.AnyBlockVotes() != (len(e.blockVotes.Votes) != 0) { 252 return ErrSerMalformedEvent 253 } 254 err := e.Event.MarshalCSER(w) 255 if err != nil { 256 return err 257 } 258 w.FixedBytes(e.sig.Bytes()) 259 if e.AnyTxs() { 260 if e.Version() == 0 { 261 // Txs are serialized with CSER for legacy events 262 err = MarshalTxsCSER(e.txs, w) 263 if err != nil { 264 return err 265 } 266 } else { 267 b, err := rlp.EncodeToBytes(e.txs) 268 if err != nil { 269 return err 270 } 271 w.SliceBytes(b) 272 } 273 } 274 if e.AnyMisbehaviourProofs() { 275 b, err := rlp.EncodeToBytes(e.misbehaviourProofs) 276 if err != nil { 277 return err 278 } 279 w.SliceBytes(b) 280 } 281 if e.AnyEpochVote() { 282 err = e.EpochVote().MarshalCSER(w) 283 if err != nil { 284 return err 285 } 286 } 287 if e.AnyBlockVotes() { 288 err = e.BlockVotes().MarshalCSER(w) 289 if err != nil { 290 return err 291 } 292 } 293 return nil 294 } 295 296 func (e *MutableEventPayload) UnmarshalCSER(r *cser.Reader) error { 297 err := eventUnmarshalCSER(r, e) 298 if err != nil { 299 return err 300 } 301 r.FixedBytes(e.sig[:]) 302 // txs 303 txs := make(types.Transactions, 0, 4) 304 if e.AnyTxs() { 305 if e.version == 0 { 306 // txs size 307 size := r.U56() 308 if size == 0 { 309 return cser.ErrNonCanonicalEncoding 310 } 311 if size > ProtocolMaxMsgSize/64 { 312 return cser.ErrTooLargeAlloc 313 } 314 for i := uint64(0); i < size; i++ { 315 tx, err := TransactionUnmarshalCSER(r) 316 if err != nil { 317 return err 318 } 319 txs = append(txs, tx) 320 } 321 } else { 322 b := r.SliceBytes(ProtocolMaxMsgSize) 323 err := rlp.DecodeBytes(b, &txs) 324 if err != nil { 325 return err 326 } 327 } 328 } 329 e.txs = txs 330 // mps 331 mps := make([]MisbehaviourProof, 0) 332 if e.AnyMisbehaviourProofs() { 333 b := r.SliceBytes(ProtocolMaxMsgSize) 334 err := rlp.DecodeBytes(b, &mps) 335 if err != nil { 336 return err 337 } 338 } 339 e.misbehaviourProofs = mps 340 // ev 341 ev := LlrEpochVote{} 342 if e.AnyEpochVote() { 343 err := ev.UnmarshalCSER(r) 344 if err != nil { 345 return err 346 } 347 if ev.Epoch == 0 { 348 return cser.ErrNonCanonicalEncoding 349 } 350 } 351 e.epochVote = ev 352 // bvs 353 bvs := LlrBlockVotes{Votes: make([]hash.Hash, 0, 2)} 354 if e.AnyBlockVotes() { 355 err := bvs.UnmarshalCSER(r) 356 if err != nil { 357 return err 358 } 359 if len(bvs.Votes) == 0 || bvs.Start == 0 || bvs.Epoch == 0 { 360 return cser.ErrNonCanonicalEncoding 361 } 362 } 363 e.blockVotes = bvs 364 return nil 365 } 366 367 // MarshalBinary implements encoding.BinaryMarshaller interface. 368 func (e *EventPayload) MarshalBinary() ([]byte, error) { 369 return cser.MarshalBinaryAdapter(e.MarshalCSER) 370 } 371 372 // UnmarshalBinary implements encoding.BinaryUnmarshaller interface. 373 func (e *MutableEventPayload) UnmarshalBinary(raw []byte) (err error) { 374 return cser.UnmarshalBinaryAdapter(raw, e.UnmarshalCSER) 375 } 376 377 // UnmarshalBinary implements encoding.BinaryUnmarshaller interface. 378 func (e *EventPayload) UnmarshalBinary(raw []byte) (err error) { 379 mutE := MutableEventPayload{} 380 err = mutE.UnmarshalBinary(raw) 381 if err != nil { 382 return err 383 } 384 eventSer, _ := mutE.immutable().Event.MarshalBinary() 385 locatorHash, baseHash := calcEventHashes(eventSer, &mutE) 386 *e = *mutE.build(locatorHash, baseHash, len(raw)) 387 return nil 388 } 389 390 // EncodeRLP implements rlp.Encoder interface. 391 func (e *EventPayload) EncodeRLP(w io.Writer) error { 392 bytes, err := e.MarshalBinary() 393 if err != nil { 394 return err 395 } 396 397 err = rlp.Encode(w, &bytes) 398 399 return err 400 } 401 402 // DecodeRLP implements rlp.Decoder interface. 403 func (e *EventPayload) DecodeRLP(src *rlp.Stream) error { 404 bytes, err := src.Bytes() 405 if err != nil { 406 return err 407 } 408 409 return e.UnmarshalBinary(bytes) 410 } 411 412 // DecodeRLP implements rlp.Decoder interface. 413 func (e *MutableEventPayload) DecodeRLP(src *rlp.Stream) error { 414 bytes, err := src.Bytes() 415 if err != nil { 416 return err 417 } 418 419 return e.UnmarshalBinary(bytes) 420 } 421 422 // RPCMarshalEvent converts the given event to the RPC output . 423 func RPCMarshalEvent(e EventI) map[string]interface{} { 424 return map[string]interface{}{ 425 "version": hexutil.Uint64(e.Version()), 426 "networkVersion": hexutil.Uint64(e.NetForkID()), 427 "epoch": hexutil.Uint64(e.Epoch()), 428 "seq": hexutil.Uint64(e.Seq()), 429 "id": hexutil.Bytes(e.ID().Bytes()), 430 "frame": hexutil.Uint64(e.Frame()), 431 "creator": hexutil.Uint64(e.Creator()), 432 "prevEpochHash": e.PrevEpochHash(), 433 "parents": EventIDsToHex(e.Parents()), 434 "lamport": hexutil.Uint64(e.Lamport()), 435 "creationTime": hexutil.Uint64(e.CreationTime()), 436 "medianTime": hexutil.Uint64(e.MedianTime()), 437 "extraData": hexutil.Bytes(e.Extra()), 438 "payloadHash": hexutil.Bytes(e.PayloadHash().Bytes()), 439 "gasPowerLeft": map[string]interface{}{ 440 "shortTerm": hexutil.Uint64(e.GasPowerLeft().Gas[ShortTermGas]), 441 "longTerm": hexutil.Uint64(e.GasPowerLeft().Gas[LongTermGas]), 442 }, 443 "gasPowerUsed": hexutil.Uint64(e.GasPowerUsed()), 444 "anyTxs": e.AnyTxs(), 445 "anyMisbehaviourProofs": e.AnyMisbehaviourProofs(), 446 "anyEpochVote": e.AnyEpochVote(), 447 "anyBlockVotes": e.AnyBlockVotes(), 448 } 449 } 450 451 // RPCUnmarshalEvent converts the RPC output to the header. 452 func RPCUnmarshalEvent(fields map[string]interface{}) EventI { 453 mustBeUint64 := func(name string) uint64 { 454 s := fields[name].(string) 455 return hexutil.MustDecodeUint64(s) 456 } 457 mustBeBytes := func(name string) []byte { 458 s := fields[name].(string) 459 return hexutil.MustDecode(s) 460 } 461 mustBeID := func(name string) (id [24]byte) { 462 s := fields[name].(string) 463 bb := hexutil.MustDecode(s) 464 copy(id[:], bb) 465 return 466 } 467 mustBeBool := func(name string) bool { 468 return fields[name].(bool) 469 } 470 mayBeHash := func(name string) *hash.Hash { 471 s, ok := fields[name].(string) 472 if !ok { 473 return nil 474 } 475 bb := hexutil.MustDecode(s) 476 h := hash.BytesToHash(bb) 477 return &h 478 } 479 480 e := MutableEventPayload{} 481 482 e.SetVersion(uint8(mustBeUint64("version"))) 483 e.SetNetForkID(uint16(mustBeUint64("networkVersion"))) 484 e.SetEpoch(idx.Epoch(mustBeUint64("epoch"))) 485 e.SetSeq(idx.Event(mustBeUint64("seq"))) 486 e.SetID(mustBeID("id")) 487 e.SetFrame(idx.Frame(mustBeUint64("frame"))) 488 e.SetCreator(idx.ValidatorID(mustBeUint64("creator"))) 489 e.SetPrevEpochHash(mayBeHash("prevEpochHash")) 490 e.SetParents(HexToEventIDs(fields["parents"].([]interface{}))) 491 e.SetLamport(idx.Lamport(mustBeUint64("lamport"))) 492 e.SetCreationTime(Timestamp(mustBeUint64("creationTime"))) 493 e.SetMedianTime(Timestamp(mustBeUint64("medianTime"))) 494 e.SetExtra(mustBeBytes("extraData")) 495 e.SetPayloadHash(*mayBeHash("payloadHash")) 496 e.SetGasPowerUsed(mustBeUint64("gasPowerUsed")) 497 e.anyTxs = mustBeBool("anyTxs") 498 e.anyMisbehaviourProofs = mustBeBool("anyMisbehaviourProofs") 499 e.anyEpochVote = mustBeBool("anyEpochVote") 500 e.anyBlockVotes = mustBeBool("anyBlockVotes") 501 502 gas := GasPowerLeft{} 503 obj := fields["gasPowerLeft"].(map[string]interface{}) 504 gas.Gas[ShortTermGas] = hexutil.MustDecodeUint64(obj["shortTerm"].(string)) 505 gas.Gas[LongTermGas] = hexutil.MustDecodeUint64(obj["longTerm"].(string)) 506 e.SetGasPowerLeft(gas) 507 508 return &e.Build().Event 509 } 510 511 // RPCMarshalEventPayload converts the given event to the RPC output which depends on fullTx. If inclTx is true transactions are 512 // returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain 513 // transaction hashes. 514 func RPCMarshalEventPayload(event EventPayloadI, inclTx bool, fullTx bool) (map[string]interface{}, error) { 515 fields := RPCMarshalEvent(event) 516 fields["size"] = hexutil.Uint64(event.Size()) 517 518 if inclTx { 519 formatTx := func(tx *types.Transaction) (interface{}, error) { 520 return tx.Hash(), nil 521 } 522 if fullTx { 523 // TODO: full txs for events API 524 panic("is not implemented") 525 //formatTx = func(tx *types.Transaction) (interface{}, error) { 526 // return newRPCTransactionFromBlockHash(event, tx.Hash()), nil 527 //} 528 } 529 txs := event.Txs() 530 transactions := make([]interface{}, len(txs)) 531 var err error 532 for i, tx := range txs { 533 if transactions[i], err = formatTx(tx); err != nil { 534 return nil, err 535 } 536 } 537 538 fields["transactions"] = transactions 539 } 540 541 return fields, nil 542 } 543 544 func EventIDsToHex(ids hash.Events) []hexutil.Bytes { 545 res := make([]hexutil.Bytes, len(ids)) 546 for i, id := range ids { 547 res[i] = hexutil.Bytes(id.Bytes()) 548 } 549 return res 550 } 551 552 func HexToEventIDs(bb []interface{}) hash.Events { 553 res := make(hash.Events, len(bb)) 554 for i, b := range bb { 555 res[i] = hash.BytesToEvent(hexutil.MustDecode(b.(string))) 556 } 557 return res 558 }