Search in sources :

Example 96 with Transaction

use of org.hyperledger.besu.ethereum.core.Transaction in project besu by hyperledger.

the class TransactionSimulator method processWithWorldUpdater.

@Nonnull
public Optional<TransactionSimulatorResult> processWithWorldUpdater(final CallParameter callParams, final TransactionValidationParams transactionValidationParams, final OperationTracer operationTracer, final BlockHeader header, final WorldUpdater updater) {
    final ProtocolSpec protocolSpec = protocolSchedule.getByBlockNumber(header.getNumber());
    final Address senderAddress = callParams.getFrom() != null ? callParams.getFrom() : DEFAULT_FROM;
    BlockHeader blockHeaderToProcess = header;
    if (transactionValidationParams.isAllowExceedingBalance() && header.getBaseFee().isPresent()) {
        blockHeaderToProcess = BlockHeaderBuilder.fromHeader(header).baseFee(Wei.ZERO).blockHeaderFunctions(protocolSpec.getBlockHeaderFunctions()).buildBlockHeader();
    }
    final Account sender = updater.get(senderAddress);
    final long nonce = sender != null ? sender.getNonce() : 0L;
    final long gasLimit = callParams.getGasLimit() >= 0 ? callParams.getGasLimit() : blockHeaderToProcess.getGasLimit();
    final Wei value = callParams.getValue() != null ? callParams.getValue() : Wei.ZERO;
    final Bytes payload = callParams.getPayload() != null ? callParams.getPayload() : Bytes.EMPTY;
    final MainnetTransactionProcessor transactionProcessor = protocolSchedule.getByBlockNumber(blockHeaderToProcess.getNumber()).getTransactionProcessor();
    final Optional<Transaction> maybeTransaction = buildTransaction(callParams, transactionValidationParams, header, senderAddress, nonce, gasLimit, value, payload);
    if (maybeTransaction.isEmpty()) {
        return Optional.empty();
    }
    final Transaction transaction = maybeTransaction.get();
    final TransactionProcessingResult result = transactionProcessor.processTransaction(blockchain, updater, blockHeaderToProcess, transaction, protocolSpec.getMiningBeneficiaryCalculator().calculateBeneficiary(blockHeaderToProcess), new BlockHashLookup(blockHeaderToProcess, blockchain), false, transactionValidationParams, operationTracer);
    // If GoQuorum privacy enabled, and value = zero, get max gas possible for a PMT hash.
    // It is possible to have a data field that has a lower intrinsic value than the PMT hash.
    // This means a potential over-estimate of gas, but the tx, if sent with this gas, will not
    // fail.
    final boolean goQuorumCompatibilityMode = transactionProcessor.getTransactionValidator().getGoQuorumCompatibilityMode();
    if (goQuorumCompatibilityMode && value.isZero()) {
        final long privateGasEstimateAndState = protocolSpec.getGasCalculator().getMaximumTransactionCost(64);
        if (privateGasEstimateAndState > result.getEstimateGasUsedByTransaction()) {
            // modify the result to have the larger estimate
            final TransactionProcessingResult resultPmt = TransactionProcessingResult.successful(result.getLogs(), privateGasEstimateAndState, result.getGasRemaining(), result.getOutput(), result.getValidationResult());
            return Optional.of(new TransactionSimulatorResult(transaction, resultPmt));
        }
    }
    return Optional.of(new TransactionSimulatorResult(transaction, result));
}
Also used : Account(org.hyperledger.besu.evm.account.Account) Address(org.hyperledger.besu.datatypes.Address) TransactionProcessingResult(org.hyperledger.besu.ethereum.processing.TransactionProcessingResult) Bytes(org.apache.tuweni.bytes.Bytes) MainnetTransactionProcessor(org.hyperledger.besu.ethereum.mainnet.MainnetTransactionProcessor) Transaction(org.hyperledger.besu.ethereum.core.Transaction) BlockHashLookup(org.hyperledger.besu.ethereum.vm.BlockHashLookup) ProtocolSpec(org.hyperledger.besu.ethereum.mainnet.ProtocolSpec) Wei(org.hyperledger.besu.datatypes.Wei) BlockHeader(org.hyperledger.besu.ethereum.core.BlockHeader) Nonnull(javax.annotation.Nonnull)

Example 97 with Transaction

use of org.hyperledger.besu.ethereum.core.Transaction in project besu by hyperledger.

the class PrivateMigrationBlockProcessor method processBlock.

public AbstractBlockProcessor.Result processBlock(final Blockchain blockchain, final MutableWorldState worldState, final BlockHeader blockHeader, final List<Transaction> transactions, final List<BlockHeader> ommers) {
    long gasUsed = 0;
    final List<TransactionReceipt> receipts = new ArrayList<>();
    for (final Transaction transaction : transactions) {
        final long remainingGasBudget = blockHeader.getGasLimit() - gasUsed;
        if (Long.compareUnsigned(transaction.getGasLimit(), remainingGasBudget) > 0) {
            LOG.warn("Transaction processing error: transaction gas limit {} exceeds available block budget" + " remaining {}", transaction.getGasLimit(), remainingGasBudget);
            return AbstractBlockProcessor.Result.failed();
        }
        final WorldUpdater worldStateUpdater = worldState.updater();
        final BlockHashLookup blockHashLookup = new BlockHashLookup(blockHeader, blockchain);
        final Address miningBeneficiary = miningBeneficiaryCalculator.calculateBeneficiary(blockHeader);
        final TransactionProcessingResult result = transactionProcessor.processTransaction(blockchain, worldStateUpdater, blockHeader, transaction, miningBeneficiary, blockHashLookup, true, TransactionValidationParams.processingBlock());
        if (result.isInvalid()) {
            return AbstractBlockProcessor.Result.failed();
        }
        worldStateUpdater.commit();
        gasUsed = transaction.getGasLimit() - result.getGasRemaining() + gasUsed;
        final TransactionReceipt transactionReceipt = transactionReceiptFactory.create(transaction.getType(), result, worldState, gasUsed);
        receipts.add(transactionReceipt);
    }
    if (!rewardCoinbase(worldState, blockHeader, ommers, skipZeroBlockRewards)) {
        return AbstractBlockProcessor.Result.failed();
    }
    return AbstractBlockProcessor.Result.successful(receipts);
}
Also used : Transaction(org.hyperledger.besu.ethereum.core.Transaction) BlockHashLookup(org.hyperledger.besu.ethereum.vm.BlockHashLookup) Address(org.hyperledger.besu.datatypes.Address) WorldUpdater(org.hyperledger.besu.evm.worldstate.WorldUpdater) TransactionReceipt(org.hyperledger.besu.ethereum.core.TransactionReceipt) ArrayList(java.util.ArrayList) TransactionProcessingResult(org.hyperledger.besu.ethereum.processing.TransactionProcessingResult)

Example 98 with Transaction

use of org.hyperledger.besu.ethereum.core.Transaction in project besu by hyperledger.

the class SigningPrivateMarkerTransactionFactory method signAndBuild.

protected Bytes signAndBuild(final UnsignedPrivateMarkerTransaction unsignedPrivateMarkerTransaction, final KeyPair signingKey) {
    final Transaction transaction = Transaction.builder().type(TransactionType.FRONTIER).nonce(unsignedPrivateMarkerTransaction.getNonce()).gasPrice(unsignedPrivateMarkerTransaction.getGasPrice().map(Wei::fromQuantity).orElse(null)).gasLimit(unsignedPrivateMarkerTransaction.getGasLimit()).to(Address.fromPlugin(unsignedPrivateMarkerTransaction.getTo().get())).value(Wei.fromQuantity(unsignedPrivateMarkerTransaction.getValue())).payload(unsignedPrivateMarkerTransaction.getPayload()).signAndBuild(signingKey);
    final BytesValueRLPOutput out = new BytesValueRLPOutput();
    transaction.writeTo(out);
    return out.encoded();
}
Also used : UnsignedPrivateMarkerTransaction(org.hyperledger.besu.plugin.data.UnsignedPrivateMarkerTransaction) Transaction(org.hyperledger.besu.ethereum.core.Transaction) BytesValueRLPOutput(org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput)

Example 99 with Transaction

use of org.hyperledger.besu.ethereum.core.Transaction in project besu by hyperledger.

the class PrivateStorageMigration method migratePrivateStorage.

public void migratePrivateStorage() {
    final long migrationStartTimestamp = System.currentTimeMillis();
    final long chainHeadBlockNumber = blockchain.getChainHeadBlockNumber();
    LOG.info("Migrating private storage database...");
    for (long blockNumber = 0; blockNumber <= chainHeadBlockNumber; blockNumber++) {
        final Block block = blockchain.getBlockByNumber(blockNumber).orElseThrow(PrivateStorageMigrationException::new);
        final Hash blockHash = block.getHash();
        final BlockHeader blockHeader = block.getHeader();
        LOG.info("Processing block {} ({}/{})", blockHash, blockNumber, chainHeadBlockNumber);
        createPrivacyGroupHeadBlockMap(blockHeader);
        final int lastPmtIndex = findLastPMTIndexInBlock(block);
        if (lastPmtIndex >= 0) {
            final ProtocolSpec protocolSpec = protocolSchedule.getByBlockNumber(blockNumber);
            final PrivateMigrationBlockProcessor privateMigrationBlockProcessor = privateMigrationBlockProcessorBuilder.apply(protocolSpec);
            final MutableWorldState publicWorldState = blockchain.getBlockHeader(blockHeader.getParentHash()).flatMap(header -> publicWorldStateArchive.getMutable(header.getStateRoot(), header.getHash())).orElseThrow(PrivateStorageMigrationException::new);
            final List<Transaction> transactionsToProcess = block.getBody().getTransactions().subList(0, lastPmtIndex + 1);
            final List<BlockHeader> ommers = block.getBody().getOmmers();
            privateMigrationBlockProcessor.processBlock(blockchain, publicWorldState, blockHeader, transactionsToProcess, ommers);
        }
    }
    if (isResultingPrivateStateRootAtHeadValid()) {
        privateStateStorage.updater().putDatabaseVersion(SCHEMA_VERSION_1_4_0).commit();
    } else {
        throw new PrivateStorageMigrationException("Inconsistent state root. Please re-sync.");
    }
    final long migrationDuration = System.currentTimeMillis() - migrationStartTimestamp;
    LOG.info("Migration took {} seconds", migrationDuration / 1000.0);
}
Also used : PrivateStateRootResolver(org.hyperledger.besu.ethereum.privacy.PrivateStateRootResolver) Logger(org.slf4j.Logger) BlockHeader(org.hyperledger.besu.ethereum.core.BlockHeader) Blockchain(org.hyperledger.besu.ethereum.chain.Blockchain) LoggerFactory(org.slf4j.LoggerFactory) Set(java.util.Set) MutableWorldState(org.hyperledger.besu.ethereum.core.MutableWorldState) PrivateStateStorage(org.hyperledger.besu.ethereum.privacy.storage.PrivateStateStorage) Address(org.hyperledger.besu.datatypes.Address) Function(java.util.function.Function) ProtocolSchedule(org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule) LegacyPrivateStateStorage(org.hyperledger.besu.ethereum.privacy.storage.LegacyPrivateStateStorage) List(java.util.List) SCHEMA_VERSION_1_4_0(org.hyperledger.besu.ethereum.privacy.storage.PrivateStateKeyValueStorage.SCHEMA_VERSION_1_4_0) WorldStateArchive(org.hyperledger.besu.ethereum.worldstate.WorldStateArchive) Optional(java.util.Optional) Block(org.hyperledger.besu.ethereum.core.Block) ProtocolSpec(org.hyperledger.besu.ethereum.mainnet.ProtocolSpec) Transaction(org.hyperledger.besu.ethereum.core.Transaction) PrivacyGroupHeadBlockMap(org.hyperledger.besu.ethereum.privacy.storage.PrivacyGroupHeadBlockMap) Bytes32(org.apache.tuweni.bytes.Bytes32) Hash(org.hyperledger.besu.datatypes.Hash) MutableWorldState(org.hyperledger.besu.ethereum.core.MutableWorldState) Hash(org.hyperledger.besu.datatypes.Hash) Transaction(org.hyperledger.besu.ethereum.core.Transaction) ProtocolSpec(org.hyperledger.besu.ethereum.mainnet.ProtocolSpec) Block(org.hyperledger.besu.ethereum.core.Block) BlockHeader(org.hyperledger.besu.ethereum.core.BlockHeader)

Example 100 with Transaction

use of org.hyperledger.besu.ethereum.core.Transaction in project besu by hyperledger.

the class TransactionPool method validateTransaction.

private ValidationResult<TransactionInvalidReason> validateTransaction(final Transaction transaction, final boolean isLocal) {
    final BlockHeader chainHeadBlockHeader = getChainHeadBlockHeader();
    final FeeMarket feeMarket = protocolSchedule.getByBlockNumber(chainHeadBlockHeader.getNumber()).getFeeMarket();
    // Check whether it's a GoQuorum transaction
    boolean goQuorumCompatibilityMode = getTransactionValidator().getGoQuorumCompatibilityMode();
    if (transaction.isGoQuorumPrivateTransaction(goQuorumCompatibilityMode)) {
        final Optional<Wei> weiValue = ofNullable(transaction.getValue());
        if (weiValue.isPresent() && !weiValue.get().isZero()) {
            return ValidationResult.invalid(TransactionInvalidReason.ETHER_VALUE_NOT_SUPPORTED);
        }
    }
    // executable:
    if ((!effectiveGasPriceIsAboveConfiguredMinGasPrice(transaction) && !miningParameters.isMiningEnabled()) || (!feeMarket.satisfiesFloorTxCost(transaction))) {
        return ValidationResult.invalid(TransactionInvalidReason.GAS_PRICE_TOO_LOW);
    }
    final ValidationResult<TransactionInvalidReason> basicValidationResult = getTransactionValidator().validate(transaction, chainHeadBlockHeader.getBaseFee(), TransactionValidationParams.transactionPool());
    if (!basicValidationResult.isValid()) {
        return basicValidationResult;
    }
    if (isLocal && strictReplayProtectionShouldBeEnforceLocally(chainHeadBlockHeader) && transaction.getChainId().isEmpty()) {
        // Strict replay protection is enabled but the tx is not replay-protected
        return ValidationResult.invalid(TransactionInvalidReason.REPLAY_PROTECTED_SIGNATURE_REQUIRED);
    }
    if (transaction.getGasLimit() > chainHeadBlockHeader.getGasLimit()) {
        return ValidationResult.invalid(TransactionInvalidReason.EXCEEDS_BLOCK_GAS_LIMIT, String.format("Transaction gas limit of %s exceeds block gas limit of %s", transaction.getGasLimit(), chainHeadBlockHeader.getGasLimit()));
    }
    if (transaction.getType().equals(TransactionType.EIP1559) && !feeMarket.implementsBaseFee()) {
        return ValidationResult.invalid(TransactionInvalidReason.INVALID_TRANSACTION_FORMAT, "EIP-1559 transaction are not allowed yet");
    }
    return protocolContext.getWorldStateArchive().getMutable(chainHeadBlockHeader.getStateRoot(), chainHeadBlockHeader.getHash(), false).map(worldState -> {
        final Account senderAccount = worldState.get(transaction.getSender());
        return getTransactionValidator().validateForSender(transaction, senderAccount, TransactionValidationParams.transactionPool());
    }).orElseGet(() -> ValidationResult.invalid(CHAIN_HEAD_WORLD_STATE_NOT_AVAILABLE));
}
Also used : ADDED(org.hyperledger.besu.ethereum.eth.transactions.sorter.AbstractPendingTransactionsSorter.TransactionAddedStatus.ADDED) ValidationResult(org.hyperledger.besu.ethereum.mainnet.ValidationResult) AbstractPendingTransactionsSorter(org.hyperledger.besu.ethereum.eth.transactions.sorter.AbstractPendingTransactionsSorter) Account(org.hyperledger.besu.evm.account.Account) EthPeer(org.hyperledger.besu.ethereum.eth.manager.EthPeer) LoggerFactory(org.slf4j.LoggerFactory) FeeMarket(org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket) Collections.singletonList(java.util.Collections.singletonList) MainnetTransactionValidator(org.hyperledger.besu.ethereum.mainnet.MainnetTransactionValidator) ProtocolSchedule(org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule) HashSet(java.util.HashSet) TransactionAddedStatus(org.hyperledger.besu.ethereum.eth.transactions.sorter.AbstractPendingTransactionsSorter.TransactionAddedStatus) CHAIN_HEAD_WORLD_STATE_NOT_AVAILABLE(org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason.CHAIN_HEAD_WORLD_STATE_NOT_AVAILABLE) Wei(org.hyperledger.besu.datatypes.Wei) TransactionInvalidReason(org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason) BlockAddedEvent(org.hyperledger.besu.ethereum.chain.BlockAddedEvent) BlockAddedObserver(org.hyperledger.besu.ethereum.chain.BlockAddedObserver) Logger(org.slf4j.Logger) Optional.ofNullable(java.util.Optional.ofNullable) BlockHeader(org.hyperledger.besu.ethereum.core.BlockHeader) BesuMetricCategory(org.hyperledger.besu.metrics.BesuMetricCategory) Collection(java.util.Collection) EthContext(org.hyperledger.besu.ethereum.eth.manager.EthContext) Set(java.util.Set) TransactionValidationParams(org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams) MiningParameters(org.hyperledger.besu.ethereum.core.MiningParameters) LabelledMetric(org.hyperledger.besu.plugin.services.metrics.LabelledMetric) ProtocolContext(org.hyperledger.besu.ethereum.ProtocolContext) Optional(java.util.Optional) MetricsSystem(org.hyperledger.besu.plugin.services.MetricsSystem) MutableBlockchain(org.hyperledger.besu.ethereum.chain.MutableBlockchain) TransactionType(org.hyperledger.besu.plugin.data.TransactionType) Transaction(org.hyperledger.besu.ethereum.core.Transaction) Hash(org.hyperledger.besu.datatypes.Hash) Counter(org.hyperledger.besu.plugin.services.metrics.Counter) FeeMarket(org.hyperledger.besu.ethereum.mainnet.feemarket.FeeMarket) Account(org.hyperledger.besu.evm.account.Account) TransactionInvalidReason(org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason) Wei(org.hyperledger.besu.datatypes.Wei) BlockHeader(org.hyperledger.besu.ethereum.core.BlockHeader)

Aggregations

Transaction (org.hyperledger.besu.ethereum.core.Transaction)249 Test (org.junit.Test)149 ArrayList (java.util.ArrayList)57 BlockHeader (org.hyperledger.besu.ethereum.core.BlockHeader)45 TransactionTestFixture (org.hyperledger.besu.ethereum.core.TransactionTestFixture)45 Optional (java.util.Optional)42 Hash (org.hyperledger.besu.datatypes.Hash)38 Wei (org.hyperledger.besu.datatypes.Wei)38 Block (org.hyperledger.besu.ethereum.core.Block)35 List (java.util.List)33 Address (org.hyperledger.besu.datatypes.Address)33 Account (org.hyperledger.besu.evm.account.Account)29 TransactionInvalidReason (org.hyperledger.besu.ethereum.transaction.TransactionInvalidReason)28 TransactionReceipt (org.hyperledger.besu.ethereum.core.TransactionReceipt)26 Bytes (org.apache.tuweni.bytes.Bytes)24 BlockBody (org.hyperledger.besu.ethereum.core.BlockBody)22 MiningParameters (org.hyperledger.besu.ethereum.core.MiningParameters)22 TransactionValidationParams (org.hyperledger.besu.ethereum.mainnet.TransactionValidationParams)22 KeyPair (org.hyperledger.besu.crypto.KeyPair)21 EthContext (org.hyperledger.besu.ethereum.eth.manager.EthContext)20