github.com/aergoio/aergo@v1.3.1/types/receipt.go (about) 1 package types 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "encoding/json" 7 "errors" 8 "fmt" 9 "math/big" 10 "reflect" 11 "strconv" 12 13 "github.com/aergoio/aergo/internal/enc" 14 "github.com/aergoio/aergo/internal/merkle" 15 "github.com/gogo/protobuf/jsonpb" 16 "github.com/minio/sha256-simd" 17 "github.com/willf/bloom" 18 ) 19 20 const ( 21 successStatus = iota 22 createdStatus 23 errorStatus 24 recreatedStatus 25 ) 26 27 func NewReceipt(contractAddress []byte, status string, jsonRet string) *Receipt { 28 return &Receipt{ 29 ContractAddress: contractAddress[:33], 30 Status: status, 31 Ret: jsonRet, 32 } 33 } 34 35 func (r *Receipt) marshalBody(b *bytes.Buffer, isMerkle bool) error { 36 l := make([]byte, 8) 37 b.Write(r.ContractAddress) 38 var status byte 39 switch r.Status { 40 case "SUCCESS": 41 status = successStatus 42 case "CREATED": 43 status = createdStatus 44 case "ERROR": 45 status = errorStatus 46 case "RECREATED": 47 status = recreatedStatus 48 default: 49 return errors.New("unsupported status in receipt") 50 } 51 b.WriteByte(status) 52 if !isMerkle || status != errorStatus { 53 binary.LittleEndian.PutUint32(l[:4], uint32(len(r.Ret))) 54 b.Write(l[:4]) 55 b.WriteString(r.Ret) 56 } 57 b.Write(r.TxHash) 58 59 binary.LittleEndian.PutUint32(l[:4], uint32(len(r.FeeUsed))) 60 b.Write(l[:4]) 61 b.Write(r.FeeUsed) 62 binary.LittleEndian.PutUint32(l[:4], uint32(len(r.CumulativeFeeUsed))) 63 b.Write(l[:4]) 64 b.Write(r.CumulativeFeeUsed) 65 if len(r.Bloom) == 0 { 66 b.WriteByte(0) 67 } else { 68 b.WriteByte(1) 69 b.Write(r.Bloom) 70 } 71 binary.LittleEndian.PutUint32(l[:4], uint32(len(r.Events))) 72 b.Write(l[:4]) 73 74 return nil 75 } 76 77 func (r *Receipt) marshalStoreBinary() ([]byte, error) { 78 var b bytes.Buffer 79 80 err := r.marshalBody(&b, false) 81 if err != nil { 82 return nil, err 83 } 84 for _, ev := range r.Events { 85 evB, err := ev.marshalStoreBinary(r) 86 if err != nil { 87 return nil, err 88 } 89 b.Write(evB) 90 } 91 92 return b.Bytes(), nil 93 } 94 95 func (r *Receipt) unmarshalBody(data []byte) ([]byte, uint32) { 96 r.ContractAddress = data[:33] 97 status := data[33] 98 switch status { 99 case successStatus: 100 r.Status = "SUCCESS" 101 case createdStatus: 102 r.Status = "CREATED" 103 case errorStatus: 104 r.Status = "ERROR" 105 case recreatedStatus: 106 r.Status = "RECREATED" 107 } 108 pos := uint32(34) 109 l := binary.LittleEndian.Uint32(data[pos:]) 110 pos += 4 111 r.Ret = string(data[pos : pos+l]) 112 pos += l 113 r.TxHash = data[pos : pos+32] 114 pos += 32 115 l = binary.LittleEndian.Uint32(data[pos:]) 116 pos += 4 117 r.FeeUsed = data[pos : pos+l] 118 pos += l 119 l = binary.LittleEndian.Uint32(data[pos:]) 120 pos += 4 121 r.CumulativeFeeUsed = data[pos : pos+l] 122 pos += l 123 bloomCheck := data[pos] 124 pos += 1 125 if bloomCheck == 1 { 126 r.Bloom = data[pos : pos+BloomBitByte] 127 pos += BloomBitByte 128 } 129 pos += l 130 evCount := binary.LittleEndian.Uint32(data[pos:]) 131 132 return data[pos+4:], evCount 133 } 134 135 func (r *Receipt) unmarshalStoreBinary(data []byte) ([]byte, error) { 136 evData, evCount := r.unmarshalBody(data) 137 138 r.Events = make([]*Event, evCount) 139 var err error 140 for i := uint32(0); i < evCount; i++ { 141 var ev Event 142 evData, err = ev.unmarshalStoreBinary(evData, r) 143 if err != nil { 144 return nil, err 145 } 146 r.Events[i] = &ev 147 } 148 return evData, nil 149 } 150 151 func (r *Receipt) MarshalBinary() ([]byte, error) { 152 var b bytes.Buffer 153 154 err := r.marshalBody(&b, false) 155 if err != nil { 156 return nil, err 157 } 158 for _, ev := range r.Events { 159 evB, err := ev.MarshalBinary() 160 if err != nil { 161 return nil, err 162 } 163 b.Write(evB) 164 } 165 166 return b.Bytes(), nil 167 } 168 169 func (r *Receipt) MarshalMerkleBinary() ([]byte, error) { 170 var b bytes.Buffer 171 172 err := r.marshalBody(&b, true) 173 if err != nil { 174 return nil, err 175 } 176 177 for _, ev := range r.Events { 178 evB, err := ev.MarshalMerkleBinary() 179 if err != nil { 180 return nil, err 181 } 182 b.Write(evB) 183 } 184 185 return b.Bytes(), nil 186 } 187 188 func (r *Receipt) UnmarshalBinary(data []byte) error { 189 _, err := r.ReadFrom(data) 190 return err 191 } 192 193 func (r *Receipt) ReadFrom(data []byte) ([]byte, error) { 194 evData, evCount := r.unmarshalBody(data) 195 196 r.Events = make([]*Event, evCount) 197 var err error 198 for i := uint32(0); i < evCount; i++ { 199 var ev Event 200 evData, err = ev.UnmarshalBinary(evData) 201 if err != nil { 202 return nil, err 203 } 204 r.Events[i] = &ev 205 } 206 return evData, nil 207 } 208 209 func (r *Receipt) MarshalJSONPB(*jsonpb.Marshaler) ([]byte, error) { 210 return json.Marshal(r) 211 } 212 213 func (r *Receipt) MarshalJSON() ([]byte, error) { 214 var b bytes.Buffer 215 b.WriteString(`{"BlokNo":`) 216 b.WriteString(fmt.Sprintf("%d", r.BlockNo)) 217 b.WriteString(`,"BlockHash":"`) 218 b.WriteString(enc.ToString(r.BlockHash)) 219 b.WriteString(`","contractAddress":"`) 220 b.WriteString(EncodeAddress(r.ContractAddress)) 221 b.WriteString(`","status":"`) 222 b.WriteString(r.Status) 223 if len(r.Ret) == 0 { 224 b.WriteString(`","ret": {}`) 225 } else if r.Status == "ERROR" { 226 js, _ := json.Marshal(r.Ret) 227 b.WriteString(`","ret": `) 228 b.WriteString(string(js)) 229 } else { 230 b.WriteString(`","ret": `) 231 b.WriteString(r.Ret) 232 } 233 b.WriteString(`,"txHash":"`) 234 b.WriteString(enc.ToString(r.TxHash)) 235 b.WriteString(`","txIndex":`) 236 b.WriteString(fmt.Sprintf("%d", r.TxIndex)) 237 b.WriteString(`,"from":"`) 238 b.WriteString(EncodeAddress(r.From)) 239 b.WriteString(`","to":"`) 240 b.WriteString(EncodeAddress(r.To)) 241 b.WriteString(`","usedFee":`) 242 b.WriteString(new(big.Int).SetBytes(r.FeeUsed).String()) 243 b.WriteString(`,"events":[`) 244 for i, ev := range r.Events { 245 if i != 0 { 246 b.WriteString(`,`) 247 } 248 bEv, err := ev.MarshalJSON() 249 if err != nil { 250 return nil, err 251 } 252 b.Write(bEv) 253 } 254 b.WriteString(`]}`) 255 return b.Bytes(), nil 256 } 257 258 func (r *Receipt) GetHash() []byte { 259 h := sha256.New() 260 b, _ := r.MarshalMerkleBinary() 261 h.Write(b) 262 return h.Sum(nil) 263 } 264 265 func (r *Receipt) BloomFilter(fi *FilterInfo) bool { 266 if r.Bloom == nil { 267 return false 268 } 269 270 var buffer bytes.Buffer 271 l := make([]byte, 8) 272 binary.BigEndian.PutUint64(l, BloomBitBits) 273 buffer.Write(l) 274 binary.BigEndian.PutUint64(l, BloomHashKNum) 275 buffer.Write(l) 276 binary.BigEndian.PutUint64(l, BloomBitBits) 277 buffer.Write(l) 278 buffer.Write(r.Bloom) 279 280 var bf bloom.BloomFilter 281 _, err := bf.ReadFrom(&buffer) 282 if err != nil { 283 return true 284 } 285 286 if bf.Test(fi.ContractAddress) || bf.Test([]byte(fi.EventName)) { 287 return true 288 } 289 return false 290 } 291 292 func (r *Receipt) SetMemoryInfo(blkHash []byte, blkNo BlockNo, txIdx int32) { 293 r.BlockNo = blkNo 294 r.BlockHash = blkHash 295 r.TxIndex = txIdx 296 297 for _, e := range r.Events { 298 e.SetMemoryInfo(r, blkHash, blkNo, txIdx) 299 } 300 } 301 302 type bloomFilter bloom.BloomFilter 303 304 func (bf *bloomFilter) GetHash() []byte { 305 h := sha256.New() 306 b, _ := ((*bloom.BloomFilter)(bf)).GobEncode() 307 h.Write(b) 308 return h.Sum(nil) 309 } 310 311 type Receipts struct { 312 bloom *bloomFilter 313 receipts []*Receipt 314 } 315 316 func (rs *Receipts) Get() []*Receipt { 317 if rs == nil { 318 return nil 319 } 320 return rs.receipts 321 } 322 323 func (rs *Receipts) Set(receipts []*Receipt) { 324 rs.receipts = receipts 325 } 326 327 const BloomBitByte = 256 328 const BloomBitBits = BloomBitByte * 8 329 const BloomHashKNum = 3 330 331 func (rs *Receipts) MergeBloom(bf *bloom.BloomFilter) error { 332 if rs.bloom == nil { 333 rs.bloom = (*bloomFilter)(bloom.New(BloomBitBits, BloomHashKNum)) 334 } 335 336 return (*bloom.BloomFilter)(rs.bloom).Merge(bf) 337 } 338 339 func (rs *Receipts) BloomFilter(fi *FilterInfo) bool { 340 if rs.bloom == nil { 341 return false 342 } 343 bf := (*bloom.BloomFilter)(rs.bloom) 344 if bf.Test(fi.ContractAddress) || bf.Test([]byte(fi.EventName)) { 345 return true 346 } 347 return false 348 } 349 350 func (rs *Receipts) MerkleRoot() []byte { 351 if rs == nil { 352 return merkle.CalculateMerkleRoot(nil) 353 } 354 rsSize := len(rs.receipts) 355 if rs.bloom != nil { 356 rsSize++ 357 } 358 mes := make([]merkle.MerkleEntry, rsSize) 359 for i, r := range rs.receipts { 360 mes[i] = r 361 } 362 if rs.bloom != nil { 363 mes[rsSize-1] = rs.bloom 364 } 365 return merkle.CalculateMerkleRoot(mes) 366 } 367 368 func (rs *Receipts) MarshalBinary() ([]byte, error) { 369 var b bytes.Buffer 370 l := make([]byte, 4) 371 372 if rs.bloom != nil { 373 b.WriteByte(1) 374 bloomB, err := (*bloom.BloomFilter)(rs.bloom).GobEncode() 375 if err != nil { 376 return nil, err 377 } 378 b.Write(bloomB[24:]) 379 } else { 380 b.WriteByte(0) 381 } 382 binary.LittleEndian.PutUint32(l, uint32(len(rs.receipts))) 383 b.Write(l) 384 for _, r := range rs.receipts { 385 rB, err := r.marshalStoreBinary() 386 if err != nil { 387 return nil, err 388 } 389 b.Write(rB) 390 } 391 392 return b.Bytes(), nil 393 } 394 395 func (rs *Receipts) UnmarshalBinary(data []byte) error { 396 checkBloom := data[0] 397 pos := 1 398 if checkBloom == 1 { 399 var buffer bytes.Buffer 400 var bf bloom.BloomFilter 401 l := make([]byte, 8) 402 binary.BigEndian.PutUint64(l, BloomBitBits) 403 buffer.Write(l) 404 binary.BigEndian.PutUint64(l, BloomHashKNum) 405 buffer.Write(l) 406 binary.BigEndian.PutUint64(l, BloomBitBits) 407 buffer.Write(l) 408 buffer.Write(data[pos : pos+BloomBitByte]) 409 _, err := bf.ReadFrom(&buffer) 410 if err != nil { 411 return err 412 } 413 pos += BloomBitByte 414 rs.bloom = (*bloomFilter)(&bf) 415 } 416 rCount := binary.LittleEndian.Uint32(data[pos:]) 417 pos += 4 418 rs.receipts = make([]*Receipt, rCount) 419 unread := data[pos:] 420 var err error 421 for i := uint32(0); i < rCount; i++ { 422 var r Receipt 423 unread, err = r.unmarshalStoreBinary(unread) 424 if err != nil { 425 return err 426 } 427 rs.receipts[i] = &r 428 } 429 return nil 430 } 431 432 func (ev *Event) marshalCommonBinary(b *bytes.Buffer) { 433 l := make([]byte, 4) 434 b.Write(ev.ContractAddress) 435 binary.LittleEndian.PutUint32(l, uint32(len(ev.EventName))) 436 b.Write(l) 437 b.WriteString(ev.EventName) 438 439 binary.LittleEndian.PutUint32(l, uint32(len(ev.JsonArgs))) 440 b.Write(l) 441 b.WriteString(ev.JsonArgs) 442 443 b.Write(ev.TxHash) 444 445 binary.LittleEndian.PutUint32(l, uint32(ev.EventIdx)) 446 b.Write(l) 447 } 448 449 func (ev *Event) MarshalBinary() ([]byte, error) { 450 var b bytes.Buffer 451 l := make([]byte, 8) 452 ev.marshalCommonBinary(&b) 453 454 b.Write(ev.BlockHash) 455 binary.LittleEndian.PutUint64(l[:], ev.BlockNo) 456 b.Write(l) 457 binary.LittleEndian.PutUint32(l[:4], uint32(ev.TxIndex)) 458 b.Write(l[:4]) 459 return b.Bytes(), nil 460 } 461 462 func (ev *Event) marshalStoreBinary(r *Receipt) ([]byte, error) { 463 var b bytes.Buffer 464 l := make([]byte, 4) 465 if bytes.Equal(r.ContractAddress, ev.ContractAddress) { 466 b.WriteByte(0) 467 } else { 468 b.Write(ev.ContractAddress) 469 } 470 binary.LittleEndian.PutUint32(l, uint32(len(ev.EventName))) 471 b.Write(l) 472 b.WriteString(ev.EventName) 473 474 binary.LittleEndian.PutUint32(l, uint32(len(ev.JsonArgs))) 475 b.Write(l) 476 b.WriteString(ev.JsonArgs) 477 478 binary.LittleEndian.PutUint32(l, uint32(ev.EventIdx)) 479 b.Write(l) 480 return b.Bytes(), nil 481 } 482 483 func (ev *Event) unmarshalStoreBinary(data []byte, r *Receipt) ([]byte, error) { 484 var pos uint32 485 if data[0] == 0 { 486 ev.ContractAddress = r.ContractAddress 487 pos += 1 488 } else { 489 ev.ContractAddress = data[:33] 490 pos += 33 491 } 492 l := binary.LittleEndian.Uint32(data[pos:]) 493 pos += 4 494 ev.EventName = string(data[pos : pos+l]) 495 pos += l 496 497 l = binary.LittleEndian.Uint32(data[pos:]) 498 pos += 4 499 ev.JsonArgs = string(data[pos : pos+l]) 500 pos += l 501 502 ev.EventIdx = int32(binary.LittleEndian.Uint32(data[pos:])) 503 pos += 4 504 505 return data[pos:], nil 506 } 507 508 func (ev *Event) MarshalMerkleBinary() ([]byte, error) { 509 var b bytes.Buffer 510 ev.marshalCommonBinary(&b) 511 return b.Bytes(), nil 512 } 513 514 func (ev *Event) UnmarshalBinary(data []byte) ([]byte, error) { 515 pos := uint32(33) 516 ev.ContractAddress = data[:pos] 517 518 l := binary.LittleEndian.Uint32(data[33:]) 519 pos += 4 520 ev.EventName = string(data[pos : pos+l]) 521 pos += l 522 523 l = binary.LittleEndian.Uint32(data[pos:]) 524 pos += 4 525 ev.JsonArgs = string(data[pos : pos+l]) 526 pos += l 527 528 ev.TxHash = data[pos : pos+32] 529 pos += 32 530 531 ev.EventIdx = int32(binary.LittleEndian.Uint32(data[pos:])) 532 pos += 4 533 534 ev.BlockHash = data[pos : pos+32] 535 pos += 32 536 537 ev.BlockNo = binary.LittleEndian.Uint64(data[pos:]) 538 pos += 8 539 540 ev.TxIndex = int32(binary.LittleEndian.Uint32(data[pos:])) 541 542 return data[pos+4:], nil 543 } 544 545 func (ev *Event) MarshalJSON() ([]byte, error) { 546 var b bytes.Buffer 547 b.WriteString(`{"contractAddress":"`) 548 b.WriteString(EncodeAddress(ev.ContractAddress)) 549 b.WriteString(`","eventName":"`) 550 b.WriteString(ev.EventName) 551 b.WriteString(`","Args":`) 552 b.WriteString(ev.JsonArgs) 553 b.WriteString(`,"txHash":"`) 554 b.WriteString(enc.ToString(ev.TxHash)) 555 b.WriteString(`","EventIdx":`) 556 b.WriteString(fmt.Sprintf("%d", ev.EventIdx)) 557 b.WriteString(`,"BlockHash":"`) 558 b.WriteString(enc.ToString(ev.BlockHash)) 559 b.WriteString(`","BlockNo":`) 560 b.WriteString(fmt.Sprintf("%d", ev.BlockNo)) 561 b.WriteString(`,"TxIndex":`) 562 b.WriteString(fmt.Sprintf("%d", ev.TxIndex)) 563 b.WriteString(`}`) 564 return b.Bytes(), nil 565 } 566 567 func (ev *Event) SetMemoryInfo(receipt *Receipt, blkHash []byte, blkNo BlockNo, txIdx int32) { 568 ev.TxHash = receipt.TxHash 569 ev.TxIndex = txIdx 570 ev.BlockHash = blkHash 571 ev.BlockNo = blkNo 572 } 573 574 func checkSameArray(value []interface{}, check []interface{}) bool { 575 if len(value) != len(check) { 576 return false 577 } 578 for i, v := range value { 579 if checkValue(v, check[i]) == false { 580 return false 581 } 582 } 583 return true 584 } 585 586 func checkSameMap(value map[string]interface{}, check map[string]interface{}) bool { 587 if len(value) != len(check) { 588 return false 589 } 590 for k, v := range value { 591 if checkValue(v, check[k]) == false { 592 return false 593 } 594 } 595 return true 596 } 597 598 func checkValue(value interface{}, check interface{}) bool { 599 if reflect.TypeOf(value) != reflect.TypeOf(check) { 600 return false 601 } 602 switch value.(type) { 603 case string: 604 if value.(string) != check.(string) { 605 return false 606 } 607 case float64: 608 if value.(float64) != check.(float64) { 609 return false 610 } 611 case bool: 612 if value.(bool) != check.(bool) { 613 return false 614 } 615 case json.Number: 616 if value.(json.Number) != check.(json.Number) { 617 return false 618 } 619 case nil: 620 return true 621 case []interface{}: 622 return checkSameArray(value.([]interface{}), check.([]interface{})) 623 case map[string]interface{}: 624 return checkSameMap(value.(map[string]interface{}), check.(map[string]interface{})) 625 default: 626 return false 627 } 628 629 return true 630 } 631 632 func (ev *Event) Filter(filter *FilterInfo, argFilter []ArgFilter) bool { 633 if filter.ContractAddress != nil && !bytes.Equal(ev.ContractAddress, filter.ContractAddress) { 634 return false 635 } 636 if len(filter.EventName) != 0 && ev.EventName != filter.EventName { 637 return false 638 } 639 if argFilter != nil { 640 var args []interface{} 641 err := json.Unmarshal([]byte(ev.JsonArgs), &args) 642 if err != nil { 643 return false 644 } 645 argLen := len(args) 646 for _, filter := range argFilter { 647 if filter.argNo >= argLen { 648 return false 649 } 650 value := args[filter.argNo] 651 check := filter.value 652 if checkValue(value, check) == false { 653 return false 654 } 655 } 656 } 657 ev.ContractAddress = AddressOrigin(ev.ContractAddress) 658 return true 659 } 660 661 type ArgFilter struct { 662 argNo int 663 value interface{} 664 } 665 666 const MAXBLOCKRANGE = 10000 667 const padprefix = 0x80 668 669 func AddressPadding(addr []byte) []byte { 670 id := make([]byte, AddressLength) 671 id[0] = padprefix 672 copy(id[1:], addr) 673 return id 674 } 675 func AddressOrigin(addr []byte) []byte { 676 if addr[0] == padprefix { 677 addr = addr[1:bytes.IndexByte(addr, 0)] 678 } 679 return addr 680 } 681 682 func (fi *FilterInfo) ValidateCheck(to uint64) error { 683 if fi.ContractAddress == nil { 684 return errors.New("invalid contractAddress:" + string(fi.ContractAddress)) 685 } 686 if len(fi.ContractAddress) < AddressLength { 687 fi.ContractAddress = AddressPadding(fi.ContractAddress) 688 } else if len(fi.ContractAddress) != AddressLength { 689 return errors.New("invalid contractAddress:" + string(fi.ContractAddress)) 690 } 691 if fi.RecentBlockCnt > 0 { 692 if fi.RecentBlockCnt > MAXBLOCKRANGE { 693 return errors.New(fmt.Sprintf("too large value at recentBlockCnt %d (max %d)", 694 fi.RecentBlockCnt, MAXBLOCKRANGE)) 695 } 696 697 } else { 698 if fi.Blockfrom+MAXBLOCKRANGE < to { 699 return errors.New(fmt.Sprintf("too large block range(max %d) from %d to %d", 700 MAXBLOCKRANGE, fi.Blockfrom, to)) 701 } 702 } 703 return nil 704 } 705 706 func (fi *FilterInfo) GetExArgFilter() ([]ArgFilter, error) { 707 if len(fi.ArgFilter) == 0 { 708 return nil, nil 709 } 710 711 var argMap map[string]interface{} 712 err := json.Unmarshal(fi.ArgFilter, &argMap) 713 if err != nil { 714 return nil, errors.New("invalid json format:" + err.Error()) 715 } 716 717 argFilter := make([]ArgFilter, len(argMap)) 718 i := 0 719 for key, value := range argMap { 720 idx, err := strconv.ParseInt(key, 10, 32) 721 if err != nil || idx < 0 { 722 return nil, errors.New("invalid argument number:" + key) 723 } 724 argFilter[i].argNo = int(idx) 725 argFilter[i].value = value 726 i++ 727 } 728 if i > 0 { 729 return argFilter[:i], nil 730 } 731 return nil, nil 732 }