TransactionReceiptResult.java
/*
* Copyright ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.results;
import org.hyperledger.besu.datatypes.Address;
import org.hyperledger.besu.datatypes.Hash;
import org.hyperledger.besu.datatypes.TransactionType;
import org.hyperledger.besu.ethereum.api.query.TransactionReceiptWithMetadata;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.TransactionReceipt;
import org.hyperledger.besu.evm.log.Log;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import org.apache.tuweni.bytes.Bytes;
@JsonPropertyOrder({
"blockHash",
"blockNumber",
"contractAddress",
"cumulativeGasUsed",
"from",
"gasUsed",
"effectiveGasPrice",
"logs",
"logsBloom",
"root",
"status",
"to",
"transactionHash",
"transactionIndex",
"revertReason",
"type",
"blobGasUsed",
"blobGasPrice"
})
public abstract class TransactionReceiptResult {
private final String blockHash;
private final String blockNumber;
private final String contractAddress;
private final String cumulativeGasUsed;
private final String from;
private final String gasUsed;
private final String effectiveGasPrice;
private final List<TransactionReceiptLogResult> logs;
private final String logsBloom;
private final String to;
private final String transactionHash;
private final String transactionIndex;
private final String revertReason;
protected final TransactionReceipt receipt;
protected final String type;
private final String blobGasUsed;
private final String blobGasPrice;
protected TransactionReceiptResult(final TransactionReceiptWithMetadata receiptWithMetadata) {
final Transaction txn = receiptWithMetadata.getTransaction();
this.receipt = receiptWithMetadata.getReceipt();
this.blockHash = receiptWithMetadata.getBlockHash().toString();
this.blockNumber = Quantity.create(receiptWithMetadata.getBlockNumber());
this.contractAddress = txn.contractAddress().map(Address::toString).orElse(null);
this.cumulativeGasUsed = Quantity.create(receipt.getCumulativeGasUsed());
this.from = txn.getSender().toString();
this.gasUsed = Quantity.create(receiptWithMetadata.getGasUsed());
this.blobGasUsed = receiptWithMetadata.getBlobGasUsed().map(Quantity::create).orElse(null);
this.blobGasPrice = receiptWithMetadata.getBlobGasPrice().map(Quantity::create).orElse(null);
this.effectiveGasPrice =
Quantity.create(txn.getEffectiveGasPrice(receiptWithMetadata.getBaseFee()));
this.logs =
logReceipts(
receipt.getLogsList(),
receiptWithMetadata.getBlockNumber(),
txn.getHash(),
receiptWithMetadata.getBlockHash(),
receiptWithMetadata.getTransactionIndex(),
receiptWithMetadata.getLogIndexOffset());
this.logsBloom = receipt.getBloomFilter().toString();
this.to = txn.getTo().map(Bytes::toHexString).orElse(null);
this.transactionHash = txn.getHash().toString();
this.transactionIndex = Quantity.create(receiptWithMetadata.getTransactionIndex());
this.revertReason = receipt.getRevertReason().map(Bytes::toString).orElse(null);
this.type =
txn.getType().equals(TransactionType.FRONTIER)
? Quantity.create(0)
: Quantity.create(txn.getType().getSerializedType());
}
@JsonGetter(value = "blockHash")
public String getBlockHash() {
return blockHash;
}
@JsonGetter(value = "blockNumber")
public String getBlockNumber() {
return blockNumber;
}
@JsonGetter(value = "contractAddress")
public String getContractAddress() {
return contractAddress;
}
@JsonGetter(value = "cumulativeGasUsed")
public String getCumulativeGasUsed() {
return cumulativeGasUsed;
}
@JsonGetter(value = "from")
public String getFrom() {
return from;
}
@JsonGetter(value = "gasUsed")
public String getGasUsed() {
return gasUsed;
}
@JsonGetter(value = "blobGasUsed")
@JsonInclude(JsonInclude.Include.NON_NULL)
public String getBlobGasUsed() {
return blobGasUsed;
}
@JsonGetter(value = "blobGasPrice")
@JsonInclude(JsonInclude.Include.NON_NULL)
public String getBlobGasPrice() {
return blobGasPrice;
}
@JsonGetter(value = "effectiveGasPrice")
public String getEffectiveGasPrice() {
return effectiveGasPrice;
}
@JsonGetter(value = "logs")
public List<TransactionReceiptLogResult> getLogs() {
return logs;
}
@JsonGetter(value = "logsBloom")
public String getLogsBloom() {
return logsBloom;
}
@JsonGetter(value = "to")
public String getTo() {
return to;
}
@JsonGetter(value = "transactionHash")
public String getTransactionHash() {
return transactionHash;
}
@JsonGetter(value = "transactionIndex")
public String getTransactionIndex() {
return transactionIndex;
}
@JsonGetter(value = "type")
public String getType() {
return type;
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonGetter(value = "revertReason")
public String getRevertReason() {
return revertReason;
}
private List<TransactionReceiptLogResult> logReceipts(
final List<Log> logs,
final long blockNumber,
final Hash transactionHash,
final Hash blockHash,
final int transactionIndex,
final int logIndexOffset) {
final List<TransactionReceiptLogResult> logResults = new ArrayList<>(logs.size());
for (int i = 0; i < logs.size(); i++) {
final Log log = logs.get(i);
logResults.add(
new TransactionReceiptLogResult(
log, blockNumber, transactionHash, blockHash, transactionIndex, i + logIndexOffset));
}
return logResults;
}
}