github.com/klaytn/klaytn@v1.12.1/blockchain/types/receipt.go (about) 1 // Modifications Copyright 2018 The klaytn Authors 2 // Copyright 2015 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from core/types/receipt.go (2018/06/04). 19 // Modified and improved for the klaytn development. 20 21 package types 22 23 import ( 24 "fmt" 25 "io" 26 "unsafe" 27 28 "github.com/klaytn/klaytn/common" 29 "github.com/klaytn/klaytn/common/hexutil" 30 "github.com/klaytn/klaytn/log" 31 "github.com/klaytn/klaytn/rlp" 32 ) 33 34 //go:generate gencodec -type Receipt -field-override receiptMarshaling -out gen_receipt_json.go 35 36 var ( 37 receiptStatusFailedRLP = []byte{} 38 receiptStatusSuccessfulRLP = []byte{0x01} 39 logger = log.NewModuleLogger(log.BlockchainTypes) 40 ) 41 42 const ( 43 // ReceiptStatusFailed is the status code of a transaction if execution failed. 44 ReceiptStatusFailed = uint(0) 45 46 // ReceiptStatusSuccessful is the status code of a transaction if execution succeeded. 47 ReceiptStatusSuccessful = uint(1) 48 49 // TODO-Klaytn Enable more error below. 50 // Klaytn specific 51 // NOTE-Klaytn Value should be consecutive from ReceiptStatusFailed to the last ReceiptStatusLast 52 // Add a new ReceiptStatusErrXXX before ReceiptStatusLast 53 ReceiptStatusErrDefault = uint(0x02) // Default 54 ReceiptStatusErrDepth = uint(0x03) 55 ReceiptStatusErrContractAddressCollision = uint(0x04) 56 ReceiptStatusErrCodeStoreOutOfGas = uint(0x05) 57 ReceiptStatuserrMaxCodeSizeExceed = uint(0x06) 58 ReceiptStatusErrOutOfGas = uint(0x07) 59 ReceiptStatusErrWriteProtection = uint(0x08) 60 ReceiptStatusErrExecutionReverted = uint(0x09) 61 ReceiptStatusErrOpcodeComputationCostLimitReached = uint(0x0a) 62 ReceiptStatusErrAddressAlreadyExists = uint(0x0b) 63 ReceiptStatusErrNotAProgramAccount = uint(0x0c) 64 ReceiptStatusErrNotHumanReadableAddress = uint(0x0d) 65 ReceiptStatusErrFeeRatioOutOfRange = uint(0x0e) 66 ReceiptStatusErrAccountKeyFailNotUpdatable = uint(0x0f) 67 ReceiptStatusErrDifferentAccountKeyType = uint(0x10) 68 ReceiptStatusErrAccountKeyNilUninitializable = uint(0x11) 69 ReceiptStatusErrNotOnCurve = uint(0x12) 70 ReceiptStatusErrZeroKeyWeight = uint(0x13) 71 ReceiptStatusErrUnserializableKey = uint(0x14) 72 ReceiptStatusErrDuplicatedKey = uint(0x15) 73 ReceiptStatusErrWeightedSumOverflow = uint(0x16) 74 ReceiptStatusErrUnsatisfiableThreshold = uint(0x17) 75 ReceiptStatusErrZeroLength = uint(0x18) 76 ReceiptStatusErrLengthTooLong = uint(0x19) 77 ReceiptStatusErrNestedRoleBasedKey = uint(0x1a) 78 ReceiptStatusErrLegacyTransactionMustBeWithLegacyKey = uint(0x1b) 79 ReceiptStatusErrDeprecated = uint(0x1c) 80 ReceiptStatusErrNotSupported = uint(0x1d) 81 ReceiptStatusErrInvalidCodeFormat = uint(0x1e) 82 ReceiptStatusLast = uint(0x1f) // Last value which is not an actual ReceiptStatus 83 // ReceiptStatusErrInvalidJumpDestination // TODO-Klaytn-Issue615 84 // ReceiptStatusErrInvalidOpcode // Default case, because no static message available 85 // ReceiptStatusErrStackUnderflow // Default case, because no static message available 86 // ReceiptStatusErrStackOverflow // Default case, because no static message available 87 // ReceiptStatusErrInsufficientBalance // No receipt available for this error 88 // ReceiptStatusErrTotalTimeLimitReached // No receipt available for this error 89 // ReceiptStatusErrGasUintOverflow // TODO-Klaytn-Issue615 90 91 ) 92 93 // Receipt represents the results of a transaction. 94 type Receipt struct { 95 // Consensus fields 96 Status uint `json:"status"` 97 Bloom Bloom `json:"logsBloom" gencodec:"required"` 98 Logs []*Log `json:"logs" gencodec:"required"` 99 100 // Implementation fields (don't reorder!) 101 TxHash common.Hash `json:"transactionHash" gencodec:"required"` 102 ContractAddress common.Address `json:"contractAddress"` 103 GasUsed uint64 `json:"gasUsed" gencodec:"required"` 104 } 105 106 type receiptMarshaling struct { 107 Status hexutil.Uint 108 GasUsed hexutil.Uint64 109 } 110 111 // receiptRLP is the consensus encoding of a receipt. 112 type receiptRLP struct { 113 Status uint 114 GasUsed uint64 115 Bloom Bloom 116 Logs []*Log 117 } 118 119 type receiptStorageRLP struct { 120 Status uint 121 Bloom Bloom 122 TxHash common.Hash 123 ContractAddress common.Address 124 Logs []*LogForStorage 125 GasUsed uint64 126 } 127 128 // NewReceipt creates a barebone transaction receipt, copying the init fields. 129 func NewReceipt(status uint, txHash common.Hash, gasUsed uint64) *Receipt { 130 return &Receipt{ 131 Status: status, 132 TxHash: txHash, 133 GasUsed: gasUsed, 134 } 135 } 136 137 // EncodeRLP implements rlp.Encoder, and flattens the consensus fields of a receipt 138 // into an RLP stream. If no post state is present, byzantium fork is assumed. 139 func (r *Receipt) EncodeRLP(w io.Writer) error { 140 return rlp.Encode(w, &receiptRLP{r.Status, r.GasUsed, r.Bloom, r.Logs}) 141 } 142 143 // DecodeRLP implements rlp.Decoder, and loads the consensus fields of a receipt 144 // from an RLP stream. 145 func (r *Receipt) DecodeRLP(s *rlp.Stream) error { 146 var dec receiptRLP 147 if err := s.Decode(&dec); err != nil { 148 return err 149 } 150 r.Status = dec.Status 151 r.GasUsed, r.Bloom, r.Logs = dec.GasUsed, dec.Bloom, dec.Logs 152 return nil 153 } 154 155 // Size returns the approximate memory used by all internal contents. It is used 156 // to approximate and limit the memory consumption of various caches. 157 func (r *Receipt) Size() common.StorageSize { 158 size := common.StorageSize(unsafe.Sizeof(*r)) 159 160 size += common.StorageSize(len(r.Logs)) * common.StorageSize(unsafe.Sizeof(Log{})) 161 for _, log := range r.Logs { 162 size += common.StorageSize(len(log.Topics)*common.HashLength + len(log.Data)) 163 } 164 return size 165 } 166 167 // String implements the Stringer interface. 168 func (r *Receipt) String() string { 169 return fmt.Sprintf("receipt{status=%d gas=%v bloom=%x logs=%v}", r.Status, r.GasUsed, r.Bloom, r.Logs) 170 } 171 172 // ReceiptForStorage is a wrapper around a Receipt that flattens and parses the 173 // entire content of a receipt, as opposed to only the consensus fields originally. 174 type ReceiptForStorage Receipt 175 176 // EncodeRLP implements rlp.Encoder, and flattens all content fields of a receipt 177 // into an RLP stream. 178 func (r *ReceiptForStorage) EncodeRLP(w io.Writer) error { 179 enc := &receiptStorageRLP{ 180 Status: r.Status, 181 Bloom: r.Bloom, 182 TxHash: r.TxHash, 183 ContractAddress: r.ContractAddress, 184 Logs: make([]*LogForStorage, len(r.Logs)), 185 GasUsed: r.GasUsed, 186 } 187 for i, log := range r.Logs { 188 enc.Logs[i] = (*LogForStorage)(log) 189 } 190 return rlp.Encode(w, enc) 191 } 192 193 // DecodeRLP implements rlp.Decoder, and loads both consensus and implementation 194 // fields of a receipt from an RLP stream. 195 func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error { 196 var dec receiptStorageRLP 197 if err := s.Decode(&dec); err != nil { 198 return err 199 } 200 r.Status = dec.Status 201 202 // Assign the consensus fields 203 r.Bloom = dec.Bloom 204 r.Logs = make([]*Log, len(dec.Logs)) 205 for i, log := range dec.Logs { 206 r.Logs[i] = (*Log)(log) 207 } 208 // Assign the implementation fields 209 r.TxHash, r.ContractAddress, r.GasUsed = dec.TxHash, dec.ContractAddress, dec.GasUsed 210 return nil 211 } 212 213 // Receipts is a wrapper around a Receipt array to implement DerivableList. 214 type Receipts []*Receipt 215 216 // Len returns the number of receipts in this list. 217 func (r Receipts) Len() int { return len(r) } 218 219 // GetRlp returns the RLP encoding of one receipt from the list. 220 func (r Receipts) GetRlp(i int) []byte { 221 bytes, err := rlp.EncodeToBytes(r[i]) 222 if err != nil { 223 panic(err) 224 } 225 return bytes 226 }