github.com/iotexproject/iotex-core@v1.14.1-rc1/blockchain/block/block_deserializer.go (about) 1 // Copyright (c) 2022 IoTeX Foundation 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 package block 7 8 import ( 9 "github.com/iotexproject/iotex-proto/golang/iotextypes" 10 "github.com/pkg/errors" 11 "google.golang.org/protobuf/proto" 12 13 "github.com/iotexproject/iotex-core/action" 14 ) 15 16 // Deserializer de-serializes a block 17 // 18 // It's a wrapper to set certain parameters in order to correctly de-serialize a block 19 // Currently the parameter is EVM network ID for tx in web3 format, it is called like 20 // 21 // blk, err := (&Deserializer{}).SetEvmNetworkID(id).FromBlockProto(pbBlock) 22 // blk, err := (&Deserializer{}).SetEvmNetworkID(id).DeserializeBlock(buf) 23 type Deserializer struct { 24 evmNetworkID uint32 25 } 26 27 // NewDeserializer creates a new deserializer 28 func NewDeserializer(evmNetworkID uint32) *Deserializer { 29 return &Deserializer{ 30 evmNetworkID: evmNetworkID, 31 } 32 } 33 34 // EvmNetworkID get evm network ID 35 func (bd *Deserializer) EvmNetworkID() uint32 { return bd.evmNetworkID } 36 37 // SetEvmNetworkID sets the evm network ID for web3 actions 38 func (bd *Deserializer) SetEvmNetworkID(id uint32) *Deserializer { 39 bd.evmNetworkID = id 40 return bd 41 } 42 43 // FromBlockProto converts protobuf to block 44 func (bd *Deserializer) FromBlockProto(pbBlock *iotextypes.Block) (*Block, error) { 45 var ( 46 b = Block{} 47 err error 48 ) 49 if err = b.Header.LoadFromBlockHeaderProto(pbBlock.GetHeader()); err != nil { 50 return nil, errors.Wrap(err, "failed to deserialize block header") 51 } 52 if b.Body, err = bd.fromBodyProto(pbBlock.GetBody()); err != nil { 53 return nil, errors.Wrap(err, "failed to deserialize block body") 54 } 55 if err = b.ConvertFromBlockFooterPb(pbBlock.GetFooter()); err != nil { 56 return nil, errors.Wrap(err, "failed to deserialize block footer") 57 } 58 return &b, nil 59 } 60 61 // DeserializeBlock de-serializes a block 62 func (bd *Deserializer) DeserializeBlock(buf []byte) (*Block, error) { 63 pbBlock := iotextypes.Block{} 64 if err := proto.Unmarshal(buf, &pbBlock); err != nil { 65 return nil, errors.Wrap(err, "failed to unmarshal block") 66 } 67 b, err := bd.FromBlockProto(&pbBlock) 68 if err != nil { 69 return nil, err 70 } 71 b.Receipts = nil 72 if err = b.VerifyTxRoot(); err != nil { 73 return nil, err 74 } 75 return b, nil 76 } 77 78 // fromBodyProto converts protobuf to body 79 func (bd *Deserializer) fromBodyProto(pbBody *iotextypes.BlockBody) (Body, error) { 80 b := Body{} 81 for _, actPb := range pbBody.Actions { 82 act, err := (&action.Deserializer{}).SetEvmNetworkID(bd.evmNetworkID).ActionToSealedEnvelope(actPb) 83 if err != nil { 84 return b, errors.Wrap(err, "failed to deserialize block body") 85 } 86 b.Actions = append(b.Actions, act) 87 } 88 return b, nil 89 } 90 91 // DeserializeBody de-serializes a block body 92 func (bd *Deserializer) DeserializeBody(buf []byte) (*Body, error) { 93 pb := iotextypes.BlockBody{} 94 if err := proto.Unmarshal(buf, &pb); err != nil { 95 return nil, errors.Wrap(err, "failed to unmarshal block body") 96 } 97 b, err := bd.fromBodyProto(&pb) 98 if err != nil { 99 return nil, err 100 } 101 return &b, nil 102 } 103 104 func (bd *Deserializer) BlockFromBlockStoreProto(pb *iotextypes.BlockStore) (*Block, error) { 105 return bd.blockFromBlockStoreProto(pb) 106 } 107 108 func (bd *Deserializer) blockFromBlockStoreProto(pb *iotextypes.BlockStore) (*Block, error) { 109 blk, err := bd.FromBlockProto(pb.Block) 110 if err != nil { 111 return nil, err 112 } 113 // TODO: Reenable this if necessary 114 // // verify merkle root can match after deserialize 115 // if err := blk.VerifyTxRoot(); err != nil { 116 // return nil, err 117 // } 118 return blk, nil 119 } 120 121 func (bd *Deserializer) ReceiptsFromBlockStoreProto(pb *iotextypes.BlockStore) ([]*action.Receipt, error) { 122 return bd.receiptsFromBlockStoreProto(pb) 123 } 124 125 func (bd *Deserializer) receiptsFromBlockStoreProto(pb *iotextypes.BlockStore) ([]*action.Receipt, error) { 126 receipts := make([]*action.Receipt, 0) 127 for _, receiptPb := range pb.Receipts { 128 receipt := &action.Receipt{} 129 receipt.ConvertFromReceiptPb(receiptPb) 130 receipts = append(receipts, receipt) 131 } 132 133 return receipts, nil 134 } 135 136 // DeserializeBlockStore de-serializes a block store 137 func (bd *Deserializer) DeserializeBlockStore(buf []byte) (*Store, error) { 138 pb := iotextypes.BlockStore{} 139 if err := proto.Unmarshal(buf, &pb); err != nil { 140 return nil, errors.Wrap(err, "failed to unmarshal block store") 141 } 142 blk, err := bd.blockFromBlockStoreProto(&pb) 143 if err != nil { 144 return nil, err 145 } 146 receipts, err := bd.receiptsFromBlockStoreProto(&pb) 147 if err != nil { 148 return nil, err 149 } 150 return &Store{ 151 Block: blk, 152 Receipts: receipts, 153 }, nil 154 }