github.com/amazechain/amc@v0.1.3/common/block/receipt.go (about) 1 // Copyright 2022 The AmazeChain Authors 2 // This file is part of the AmazeChain library. 3 // 4 // The AmazeChain library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The AmazeChain library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the AmazeChain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package block 18 19 import ( 20 "bytes" 21 "fmt" 22 "github.com/amazechain/amc/api/protocol/types_pb" 23 "github.com/amazechain/amc/common/types" 24 "github.com/amazechain/amc/internal/avm/rlp" 25 "github.com/amazechain/amc/utils" 26 "github.com/holiman/uint256" 27 "google.golang.org/protobuf/proto" 28 ) 29 30 const ( 31 // ReceiptStatusFailed is the status code of a transaction if execution failed. 32 ReceiptStatusFailed = uint64(0) 33 34 // ReceiptStatusSuccessful is the status code of a transaction if execution succeeded. 35 ReceiptStatusSuccessful = uint64(1) 36 ) 37 38 type Receipts []*Receipt 39 40 func (rs *Receipts) Marshal() ([]byte, error) { 41 pb := rs.ToProtoMessage() 42 return proto.Marshal(pb) 43 } 44 45 func (rs *Receipts) Unmarshal(data []byte) error { 46 pb := new(types_pb.Receipts) 47 if err := proto.Unmarshal(data, pb); nil != err { 48 return err 49 } 50 51 return rs.FromProtoMessage(pb) 52 } 53 54 // Len returns the number of receipts in this list. 55 func (rs Receipts) Len() int { return len(rs) } 56 57 // EncodeIndex encodes the i'th receipt to w. 58 func (rs Receipts) EncodeIndex(i int, w *bytes.Buffer) { 59 r := rs[i] 60 61 logs := make([]*storedLog, len(r.Logs)) 62 63 for k, log := range r.Logs { 64 logs[k] = &storedLog{ 65 Address: log.Address, 66 Topics: log.Topics, 67 Data: log.Data, 68 } 69 } 70 data := &storedReceipt{r.Status, r.CumulativeGasUsed, logs} 71 72 rlp.Encode(w, data) 73 //byte, _ := json.Marshal(data) 74 //w.Write(byte) 75 } 76 77 func (rs *Receipts) FromProtoMessage(receipts *types_pb.Receipts) error { 78 for _, receipt := range receipts.Receipts { 79 var rec Receipt 80 err := rec.fromProtoMessage(receipt) 81 if err == nil { 82 *rs = append(*rs, &rec) 83 } 84 } 85 return nil 86 } 87 88 func (rs *Receipts) ToProtoMessage() proto.Message { 89 var receipts []*types_pb.Receipt 90 for _, receipt := range *rs { 91 pReceipt := receipt.toProtoMessage() 92 receipts = append(receipts, pReceipt.(*types_pb.Receipt)) 93 } 94 return &types_pb.Receipts{ 95 Receipts: receipts, 96 } 97 } 98 99 type Receipt struct { 100 // Consensus fields: These fields are defined by the Yellow Paper 101 Type uint8 `json:"type,omitempty"` 102 PostState []byte `json:"root"` 103 Status uint64 `json:"status"` 104 CumulativeGasUsed uint64 `json:"cumulativeGasUsed" gencodec:"required"` 105 Bloom Bloom `json:"logsBloom" gencodec:"required"` 106 Logs []*Log `json:"logs" gencodec:"required"` 107 108 // Implementation fields: These fields are added by geth when processing a transaction. 109 // They are stored in the chain database. 110 TxHash types.Hash `json:"transactionHash" gencodec:"required"` 111 ContractAddress types.Address `json:"contractAddress"` 112 GasUsed uint64 `json:"gasUsed" gencodec:"required"` 113 114 // Inclusion information: These fields provide information about the inclusion of the 115 // transaction corresponding to this receipt. 116 BlockHash types.Hash `json:"blockHash,omitempty"` 117 BlockNumber *uint256.Int `json:"blockNumber,omitempty"` 118 TransactionIndex uint `json:"transactionIndex"` 119 } 120 121 func (r *Receipt) Marshal() ([]byte, error) { 122 bpBlock := r.toProtoMessage() 123 return proto.Marshal(bpBlock) 124 } 125 126 func (r *Receipt) Unmarshal(data []byte) error { 127 var pReceipt types_pb.Receipt 128 if err := proto.Unmarshal(data, &pReceipt); err != nil { 129 return err 130 } 131 if err := r.fromProtoMessage(&pReceipt); err != nil { 132 return err 133 } 134 return nil 135 } 136 137 func (r *Receipt) toProtoMessage() proto.Message { 138 //bloom, _ := r.Bloom.Marshal() 139 140 var logs []*types_pb.Log 141 for _, log := range r.Logs { 142 logs = append(logs, log.ToProtoMessage().(*types_pb.Log)) 143 } 144 pb := &types_pb.Receipt{ 145 Type: uint32(r.Type), 146 PostState: r.PostState, 147 Status: r.Status, 148 CumulativeGasUsed: r.CumulativeGasUsed, 149 Logs: logs, 150 TxHash: utils.ConvertHashToH256(r.TxHash), 151 ContractAddress: utils.ConvertAddressToH160(r.ContractAddress), 152 GasUsed: r.GasUsed, 153 BlockHash: utils.ConvertHashToH256(r.BlockHash), 154 BlockNumber: utils.ConvertUint256IntToH256(r.BlockNumber), 155 TransactionIndex: uint64(r.TransactionIndex), 156 Bloom: utils.ConvertBytesToH2048(r.Bloom[:]), 157 } 158 return pb 159 } 160 161 func (r *Receipt) fromProtoMessage(message proto.Message) error { 162 var ( 163 pReceipt *types_pb.Receipt 164 ok bool 165 ) 166 167 if pReceipt, ok = message.(*types_pb.Receipt); !ok { 168 return fmt.Errorf("type conversion failure") 169 } 170 171 //bloom := new(types.Bloom) 172 //err := bloom.UnMarshalBloom(pReceipt.Bloom) 173 //if err != nil { 174 // return fmt.Errorf("type conversion failure bloom") 175 //} 176 177 var logs []*Log 178 for _, logMessage := range pReceipt.Logs { 179 log := new(Log) 180 181 if err := log.FromProtoMessage(logMessage); err != nil { 182 return fmt.Errorf("type conversion failure log %s", err) 183 } 184 logs = append(logs, log) 185 } 186 187 r.Type = uint8(pReceipt.Type) 188 r.PostState = pReceipt.PostState 189 r.Status = pReceipt.Status 190 r.CumulativeGasUsed = pReceipt.CumulativeGasUsed 191 r.Bloom = utils.ConvertH2048ToBloom(pReceipt.Bloom) 192 r.Logs = logs 193 r.TxHash = utils.ConvertH256ToHash(pReceipt.TxHash) 194 r.ContractAddress = utils.ConvertH160toAddress(pReceipt.ContractAddress) 195 r.GasUsed = pReceipt.GasUsed 196 r.BlockHash = utils.ConvertH256ToHash(pReceipt.BlockHash) 197 r.BlockNumber = utils.ConvertH256ToUint256Int(pReceipt.BlockNumber) 198 r.TransactionIndex = uint(pReceipt.TransactionIndex) 199 200 return nil 201 } 202 203 // storedReceipt is the consensus encoding of a receipt. 204 type storedReceipt struct { 205 PostStateOrStatus uint64 206 CumulativeGasUsed uint64 207 Logs []*storedLog 208 } 209 210 type storedLog struct { 211 Address types.Address 212 Topics []types.Hash 213 Data []byte 214 }