github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/iavl/tree_delta.go (about) 1 package iavl 2 3 import ( 4 "bytes" 5 "fmt" 6 "sort" 7 8 "github.com/pkg/errors" 9 amino "github.com/tendermint/go-amino" 10 ) 11 12 type TreeDeltaMap map[string]*TreeDelta 13 14 func (tdm TreeDeltaMap) MarshalAmino() ([]*TreeDeltaMapImp, error) { 15 keys := make([]string, len(tdm)) 16 index := 0 17 for k := range tdm { 18 keys[index] = k 19 index++ 20 } 21 sort.Strings(keys) 22 23 treeDeltaList := make([]*TreeDeltaMapImp, len(tdm)) 24 index = 0 25 for _, k := range keys { 26 treeDeltaList[index] = &TreeDeltaMapImp{Key: k, TreeValue: tdm[k]} 27 index++ 28 } 29 return treeDeltaList, nil 30 } 31 func (tdm TreeDeltaMap) UnmarshalAmino(treeDeltaList []*TreeDeltaMapImp) error { 32 for _, v := range treeDeltaList { 33 tdm[v.Key] = v.TreeValue 34 } 35 return nil 36 } 37 38 // MarshalToAmino marshal to amino bytes 39 func (tdm TreeDeltaMap) MarshalToAmino(cdc *amino.Codec) ([]byte, error) { 40 var buf bytes.Buffer 41 fieldKeysType := byte(1<<3 | 2) 42 43 if len(tdm) == 0 { 44 return buf.Bytes(), nil 45 } 46 47 keys := make([]string, len(tdm)) 48 index := 0 49 for k := range tdm { 50 keys[index] = k 51 index++ 52 } 53 sort.Strings(keys) 54 55 // encode a pair of data one by one 56 for _, k := range keys { 57 err := buf.WriteByte(fieldKeysType) 58 if err != nil { 59 return nil, err 60 } 61 62 // map must convert to new struct before it marshal 63 ti := &TreeDeltaMapImp{Key: k, TreeValue: tdm[k]} 64 data, err := ti.MarshalToAmino(cdc) 65 if err != nil { 66 return nil, err 67 } 68 // write marshal result to buffer 69 err = amino.EncodeByteSliceToBuffer(&buf, data) 70 if err != nil { 71 return nil, err 72 } 73 } 74 75 return buf.Bytes(), nil 76 } 77 78 // UnmarshalFromAmino decode bytes from amino format. 79 func (tdm TreeDeltaMap) UnmarshalFromAmino(cdc *amino.Codec, data []byte) error { 80 var dataLen uint64 = 0 81 var subData []byte 82 83 for { 84 data = data[dataLen:] 85 if len(data) == 0 { 86 break 87 } 88 pos, pbType, err := amino.ParseProtoPosAndTypeMustOneByte(data[0]) 89 if err != nil { 90 return err 91 } 92 data = data[1:] 93 94 if pbType == amino.Typ3_ByteLength { 95 var n int 96 dataLen, n, _ = amino.DecodeUvarint(data) 97 98 data = data[n:] 99 if len(data) < int(dataLen) { 100 return errors.New("not enough data") 101 } 102 subData = data[:dataLen] 103 } 104 105 switch pos { 106 case 1: 107 // a object to unmarshal data 108 ad := &TreeDeltaMapImp{} 109 err := ad.UnmarshalFromAmino(cdc, subData) 110 if err != nil { 111 return err 112 } 113 114 tdm[ad.Key] = ad.TreeValue 115 116 default: 117 return fmt.Errorf("unexpect feild num %d", pos) 118 } 119 } 120 return nil 121 } 122 123 // TreeDeltaMapImp convert map[string]*TreeDelta to struct 124 type TreeDeltaMapImp struct { 125 Key string 126 TreeValue *TreeDelta 127 } 128 129 //MarshalToAmino marshal data to amino bytes 130 func (ti *TreeDeltaMapImp) MarshalToAmino(cdc *amino.Codec) ([]byte, error) { 131 if ti == nil { 132 return nil, nil 133 } 134 var buf bytes.Buffer 135 fieldKeysType := [2]byte{1<<3 | 2, 2<<3 | 2} 136 for pos := 1; pos <= 2; pos++ { 137 switch pos { 138 case 1: 139 if len(ti.Key) == 0 { 140 break 141 } 142 err := buf.WriteByte(fieldKeysType[pos-1]) 143 if err != nil { 144 return nil, err 145 } 146 147 err = amino.EncodeStringToBuffer(&buf, ti.Key) 148 if err != nil { 149 return nil, err 150 } 151 case 2: 152 if ti.TreeValue == nil { 153 break 154 } 155 err := buf.WriteByte(fieldKeysType[pos-1]) 156 if err != nil { 157 return nil, err 158 } 159 var data []byte 160 data, err = ti.TreeValue.MarshalToAmino(cdc) 161 if err != nil { 162 return nil, err 163 } 164 165 err = amino.EncodeByteSliceToBuffer(&buf, data) 166 if err != nil { 167 return nil, err 168 } 169 170 default: 171 panic("unreachable") 172 } 173 } 174 return buf.Bytes(), nil 175 } 176 177 // UnmarshalFromAmino unmarshal data from amino bytes. 178 func (ti *TreeDeltaMapImp) UnmarshalFromAmino(cdc *amino.Codec, data []byte) error { 179 var dataLen uint64 = 0 180 var subData []byte 181 182 for { 183 data = data[dataLen:] 184 if len(data) == 0 { 185 break 186 } 187 pos, pbType, err := amino.ParseProtoPosAndTypeMustOneByte(data[0]) 188 if err != nil { 189 return err 190 } 191 data = data[1:] 192 193 if pbType == amino.Typ3_ByteLength { 194 var n int 195 dataLen, n, _ = amino.DecodeUvarint(data) 196 197 data = data[n:] 198 if len(data) < int(dataLen) { 199 return errors.New("not enough data") 200 } 201 subData = data[:dataLen] 202 } 203 204 switch pos { 205 case 1: 206 ti.Key = string(subData) 207 208 case 2: 209 tv := &TreeDelta{} 210 if len(subData) != 0 { 211 err := tv.UnmarshalFromAmino(cdc, subData) 212 if err != nil { 213 return err 214 } 215 } 216 ti.TreeValue = tv 217 218 default: 219 return fmt.Errorf("unexpect feild num %d", pos) 220 } 221 } 222 return nil 223 } 224 225 // TreeDelta is the delta for applying on new version tree 226 type TreeDelta struct { 227 NodesDelta []*NodeJsonImp `json:"nodes_delta"` 228 OrphansDelta []*NodeJson `json:"orphans_delta"` 229 CommitOrphansDelta []*CommitOrphansImp `json:"commit_orphans_delta"` 230 } 231 232 func (td *TreeDelta) MarshalToAmino(cdc *amino.Codec) ([]byte, error) { 233 var buf bytes.Buffer 234 fieldKeysType := [3]byte{1<<3 | 2, 2<<3 | 2, 3<<3 | 2} 235 for pos := 1; pos <= 3; pos++ { 236 switch pos { 237 case 1: 238 //encode data 239 for _, node := range td.NodesDelta { 240 err := buf.WriteByte(fieldKeysType[pos-1]) 241 if err != nil { 242 return nil, err 243 } 244 245 var data []byte 246 if node != nil { 247 data, err = node.MarshalToAmino(cdc) 248 if err != nil { 249 return nil, err 250 } 251 } 252 err = amino.EncodeByteSliceToBuffer(&buf, data) 253 if err != nil { 254 return nil, err 255 } 256 } 257 258 case 2: 259 for _, v := range td.OrphansDelta { 260 err := buf.WriteByte(fieldKeysType[pos-1]) 261 if err != nil { 262 return nil, err 263 } 264 var data []byte 265 if v != nil { 266 data, err = v.MarshalToAmino(nil) 267 if err != nil { 268 return nil, err 269 } 270 } 271 err = amino.EncodeByteSliceToBuffer(&buf, data) 272 if err != nil { 273 return nil, err 274 } 275 } 276 case 3: 277 for _, v := range td.CommitOrphansDelta { 278 err := buf.WriteByte(fieldKeysType[pos-1]) 279 if err != nil { 280 return nil, err 281 } 282 var data []byte 283 if v != nil { 284 data, err = v.MarshalToAmino(cdc) 285 if err != nil { 286 return nil, err 287 } 288 } 289 err = amino.EncodeByteSliceToBuffer(&buf, data) 290 if err != nil { 291 return nil, err 292 } 293 } 294 295 default: 296 panic("unreachable") 297 } 298 } 299 return buf.Bytes(), nil 300 } 301 func (td *TreeDelta) UnmarshalFromAmino(cdc *amino.Codec, data []byte) error { 302 var dataLen uint64 = 0 303 var subData []byte 304 305 for { 306 data = data[dataLen:] 307 if len(data) == 0 { 308 break 309 } 310 pos, pbType, err := amino.ParseProtoPosAndTypeMustOneByte(data[0]) 311 if err != nil { 312 return err 313 } 314 data = data[1:] 315 316 if pbType == amino.Typ3_ByteLength { 317 var n int 318 dataLen, n, _ = amino.DecodeUvarint(data) 319 320 data = data[n:] 321 if len(data) < int(dataLen) { 322 return errors.New("not enough data") 323 } 324 subData = data[:dataLen] 325 } 326 327 switch pos { 328 case 1: 329 var ni *NodeJsonImp = nil 330 if len(subData) != 0 { 331 ni = &NodeJsonImp{} 332 err := ni.UnmarshalFromAmino(cdc, subData) 333 if err != nil { 334 return err 335 } 336 } 337 td.NodesDelta = append(td.NodesDelta, ni) 338 339 case 2: 340 var nodeData *NodeJson = nil 341 if len(subData) != 0 { 342 nodeData = &NodeJson{} 343 err := nodeData.UnmarshalFromAmino(cdc, subData) 344 if err != nil { 345 return err 346 } 347 } 348 td.OrphansDelta = append(td.OrphansDelta, nodeData) 349 350 case 3: 351 var ci *CommitOrphansImp = nil 352 if len(subData) != 0 { 353 ci = &CommitOrphansImp{} 354 err := ci.UnmarshalFromAmino(cdc, subData) 355 if err != nil { 356 return err 357 } 358 } 359 td.CommitOrphansDelta = append(td.CommitOrphansDelta, ci) 360 361 default: 362 return fmt.Errorf("unexpect feild num %d", pos) 363 } 364 } 365 return nil 366 } 367 368 type NodeJsonImp struct { 369 Key string 370 NodeValue *NodeJson 371 } 372 373 // MarshalToAmino marshal data to amino bytes. 374 func (ni *NodeJsonImp) MarshalToAmino(cdc *amino.Codec) ([]byte, error) { 375 var buf bytes.Buffer 376 fieldKeysType := [2]byte{1<<3 | 2, 2<<3 | 2} 377 for pos := 1; pos <= 2; pos++ { 378 switch pos { 379 case 1: 380 if len(ni.Key) == 0 { 381 break 382 } 383 err := buf.WriteByte(fieldKeysType[pos-1]) 384 if err != nil { 385 return nil, err 386 } 387 388 err = amino.EncodeStringToBuffer(&buf, ni.Key) 389 if err != nil { 390 return nil, err 391 } 392 case 2: 393 if ni.NodeValue == nil { 394 break 395 } 396 err := buf.WriteByte(fieldKeysType[pos-1]) 397 if err != nil { 398 return nil, err 399 } 400 var data []byte 401 data, err = ni.NodeValue.MarshalToAmino(cdc) 402 if err != nil { 403 return nil, err 404 } 405 406 err = amino.EncodeByteSliceToBuffer(&buf, data) 407 if err != nil { 408 return nil, err 409 } 410 411 default: 412 panic("unreachable") 413 } 414 } 415 return buf.Bytes(), nil 416 } 417 418 // UnmarshalFromAmino unmarshal data from amino bytes. 419 func (ni *NodeJsonImp) UnmarshalFromAmino(cdc *amino.Codec, data []byte) error { 420 var dataLen uint64 = 0 421 var subData []byte 422 423 for { 424 data = data[dataLen:] 425 if len(data) == 0 { 426 break 427 } 428 pos, pbType, err := amino.ParseProtoPosAndTypeMustOneByte(data[0]) 429 if err != nil { 430 return err 431 } 432 data = data[1:] 433 434 if pbType == amino.Typ3_ByteLength { 435 var n int 436 dataLen, n, _ = amino.DecodeUvarint(data) 437 438 data = data[n:] 439 if len(data) < int(dataLen) { 440 return errors.New("not enough data") 441 } 442 subData = data[:dataLen] 443 } 444 445 switch pos { 446 case 1: 447 ni.Key = string(subData) 448 449 case 2: 450 nj := &NodeJson{} 451 if len(subData) != 0 { 452 err := nj.UnmarshalFromAmino(cdc, subData) 453 if err != nil { 454 return err 455 } 456 } 457 ni.NodeValue = nj 458 459 default: 460 return fmt.Errorf("unexpect feild num %d", pos) 461 } 462 } 463 return nil 464 } 465 466 type CommitOrphansImp struct { 467 Key string 468 CommitValue int64 469 } 470 471 // MarshalToAmino marshal data to amino bytes. 472 func (ci *CommitOrphansImp) MarshalToAmino(cdc *amino.Codec) ([]byte, error) { 473 var buf bytes.Buffer 474 //key type list 475 fieldKeysType := [2]byte{1<<3 | 2, 2 << 3} 476 477 for pos := 1; pos <= 2; pos++ { 478 switch pos { 479 case 1: 480 if len(ci.Key) == 0 { 481 break 482 } 483 err := buf.WriteByte(fieldKeysType[pos-1]) 484 if err != nil { 485 return nil, err 486 } 487 488 err = amino.EncodeStringToBuffer(&buf, ci.Key) 489 if err != nil { 490 return nil, err 491 } 492 493 case 2: 494 if ci.CommitValue == 0 { 495 break 496 } 497 err := buf.WriteByte(fieldKeysType[pos-1]) 498 if err != nil { 499 return nil, err 500 } 501 err = amino.EncodeUvarintToBuffer(&buf, uint64(ci.CommitValue)) 502 if err != nil { 503 return nil, err 504 } 505 default: 506 panic("unreachable") 507 } 508 } 509 return buf.Bytes(), nil 510 } 511 512 // UnmarshalFromAmino unmarshal data from animo bytes. 513 func (ci *CommitOrphansImp) UnmarshalFromAmino(cdc *amino.Codec, data []byte) error { 514 var dataLen uint64 = 0 515 var subData []byte 516 517 for { 518 data = data[dataLen:] 519 if len(data) == 0 { 520 break 521 } 522 pos, pbType, err := amino.ParseProtoPosAndTypeMustOneByte(data[0]) 523 if err != nil { 524 return err 525 } 526 data = data[1:] 527 528 if pbType == amino.Typ3_ByteLength { 529 var n int 530 dataLen, n, _ = amino.DecodeUvarint(data) 531 532 data = data[n:] 533 if len(data) < int(dataLen) { 534 return errors.New("not enough data") 535 } 536 subData = data[:dataLen] 537 } 538 539 switch pos { 540 case 1: 541 ci.Key = string(subData) 542 543 case 2: 544 value, n, err := amino.DecodeUvarint(data) 545 if err != nil { 546 return err 547 } 548 dataLen = uint64(n) 549 ci.CommitValue = int64(value) 550 551 default: 552 return fmt.Errorf("unexpect feild num %d", pos) 553 } 554 } 555 return nil 556 } 557 558 // NodeJson provide json Marshal of Node. 559 type NodeJson struct { 560 Key []byte `json:"key"` 561 Value []byte `json:"value"` 562 Hash []byte `json:"hash"` 563 LeftHash []byte `json:"left_hash"` 564 RightHash []byte `json:"right_hash"` 565 Version int64 `json:"version"` 566 Size int64 `json:"size"` 567 leftNode *Node 568 rightNode *Node 569 Height int8 `json:"height"` 570 Persisted bool `json:"persisted"` 571 PrePersisted bool `json:"pre_persisted"` 572 } 573 574 // MarshalToAmino marshal data to amino bytes. 575 func (nj *NodeJson) MarshalToAmino(cdc *amino.Codec) ([]byte, error) { 576 var buf bytes.Buffer 577 fieldKeysType := [10]byte{ 578 1<<3 | 2, 2<<3 | 2, 3<<3 | 2, 4<<3 | 2, 5<<3 | 2, 579 6 << 3, 7 << 3, 8 << 3, 9 << 3, 10 << 3, 580 } 581 for pos := 1; pos <= 10; pos++ { 582 switch pos { 583 case 1: 584 if len(nj.Key) == 0 { 585 break 586 } 587 err := buf.WriteByte(fieldKeysType[pos-1]) 588 if err != nil { 589 return nil, err 590 } 591 err = amino.EncodeByteSliceToBuffer(&buf, nj.Key) 592 if err != nil { 593 return nil, err 594 } 595 case 2: 596 if len(nj.Value) == 0 { 597 break 598 } 599 err := buf.WriteByte(fieldKeysType[pos-1]) 600 if err != nil { 601 return nil, err 602 } 603 err = amino.EncodeByteSliceToBuffer(&buf, nj.Value) 604 if err != nil { 605 return nil, err 606 } 607 case 3: 608 if len(nj.Hash) == 0 { 609 break 610 } 611 err := buf.WriteByte(fieldKeysType[pos-1]) 612 if err != nil { 613 return nil, err 614 } 615 err = amino.EncodeByteSliceToBuffer(&buf, nj.Hash) 616 if err != nil { 617 return nil, err 618 } 619 case 4: 620 if len(nj.LeftHash) == 0 { 621 break 622 } 623 err := buf.WriteByte(fieldKeysType[pos-1]) 624 if err != nil { 625 return nil, err 626 } 627 err = amino.EncodeByteSliceToBuffer(&buf, nj.LeftHash) 628 if err != nil { 629 return nil, err 630 } 631 case 5: 632 if len(nj.RightHash) == 0 { 633 break 634 } 635 err := buf.WriteByte(fieldKeysType[pos-1]) 636 if err != nil { 637 return nil, err 638 } 639 err = amino.EncodeByteSliceToBuffer(&buf, nj.RightHash) 640 if err != nil { 641 return nil, err 642 } 643 case 6: 644 if nj.Version == 0 { 645 break 646 } 647 err := buf.WriteByte(fieldKeysType[pos-1]) 648 if err != nil { 649 return nil, err 650 } 651 err = amino.EncodeUvarintToBuffer(&buf, uint64(nj.Version)) 652 if err != nil { 653 return nil, err 654 } 655 case 7: 656 if nj.Size == 0 { 657 break 658 } 659 err := buf.WriteByte(fieldKeysType[pos-1]) 660 if err != nil { 661 return nil, err 662 } 663 err = amino.EncodeUvarintToBuffer(&buf, uint64(nj.Size)) 664 if err != nil { 665 return nil, err 666 } 667 case 8: 668 if nj.Height == 0 { 669 break 670 } 671 err := buf.WriteByte(fieldKeysType[pos-1]) 672 if err != nil { 673 return nil, err 674 } 675 err = amino.EncodeInt8ToBuffer(&buf, nj.Height) 676 if err != nil { 677 return nil, err 678 } 679 case 9: 680 if !nj.Persisted { 681 break 682 } 683 err := buf.WriteByte(fieldKeysType[pos-1]) 684 if err != nil { 685 return nil, err 686 } 687 err = buf.WriteByte(1) 688 if err != nil { 689 return nil, err 690 } 691 case 10: 692 if !nj.PrePersisted { 693 break 694 } 695 err := buf.WriteByte(fieldKeysType[pos-1]) 696 if err != nil { 697 return nil, err 698 } 699 err = buf.WriteByte(1) 700 if err != nil { 701 return nil, err 702 } 703 704 default: 705 panic("unreachable") 706 } 707 } 708 return buf.Bytes(), nil 709 } 710 711 // UnmarshalFromAmino unmarshal data from amino bytes. 712 func (nj *NodeJson) UnmarshalFromAmino(cdc *amino.Codec, data []byte) error { 713 var dataLen uint64 = 0 714 var subData []byte 715 716 for { 717 data = data[dataLen:] 718 if len(data) == 0 { 719 break 720 } 721 pos, pbType, err := amino.ParseProtoPosAndTypeMustOneByte(data[0]) 722 if err != nil { 723 return err 724 } 725 data = data[1:] 726 727 if pbType == amino.Typ3_ByteLength { 728 var n int 729 dataLen, n, _ = amino.DecodeUvarint(data) 730 731 data = data[n:] 732 if len(data) < int(dataLen) { 733 return errors.New("not enough data") 734 } 735 subData = data[:dataLen] 736 } 737 738 switch pos { 739 case 1: 740 nj.Key = make([]byte, len(subData)) 741 copy(nj.Key, subData) 742 743 case 2: 744 nj.Value = make([]byte, len(subData)) 745 copy(nj.Value, subData) 746 747 case 3: 748 nj.Hash = make([]byte, len(subData)) 749 copy(nj.Hash, subData) 750 751 case 4: 752 nj.LeftHash = make([]byte, len(subData)) 753 copy(nj.LeftHash, subData) 754 755 case 5: 756 nj.RightHash = make([]byte, len(subData)) 757 copy(nj.RightHash, subData) 758 759 case 6: 760 value, n, err := amino.DecodeUvarint(data) 761 if err != nil { 762 return err 763 } 764 dataLen = uint64(n) 765 nj.Version = int64(value) 766 767 case 7: 768 value, n, err := amino.DecodeUvarint(data) 769 if err != nil { 770 return err 771 } 772 dataLen = uint64(n) 773 nj.Size = int64(value) 774 775 case 8: 776 value, n, err := amino.DecodeInt8(data) 777 if err != nil { 778 return err 779 } 780 dataLen = uint64(n) 781 nj.Height = value 782 783 case 9: 784 if data[0] != 0 && data[0] != 1 { 785 return fmt.Errorf("invalid Persisted") 786 } 787 nj.Persisted = data[0] == 1 788 dataLen = 1 789 790 case 10: 791 if data[0] != 0 && data[0] != 1 { 792 return fmt.Errorf("invalid prePersisted") 793 } 794 nj.PrePersisted = data[0] == 1 795 dataLen = 1 796 797 default: 798 return fmt.Errorf("unexpect feild num %d", pos) 799 } 800 } 801 return nil 802 }