Search in sources :

Example 1 with TxnParseException

use of com.radixdlt.engine.parser.exceptions.TxnParseException in project radixdlt by radixdlt.

the class RadixEngine method executeInternal.

private RadixEngineResult executeInternal(EngineStore.EngineStoreInTransaction<M> engineStoreInTransaction, List<Txn> txns, M meta, PermissionLevel permissionLevel, boolean skipAuthorization) throws RadixEngineException {
    var processedTxns = new ArrayList<REProcessedTxn>();
    // FIXME: This is quite the hack to increase sigsLeft for execution on noncommits (e.g. mempool)
    // FIXME: Should probably just change metering
    // Start with 0
    var sigsLeft = meta != null ? 0 : 1000;
    var storageStopwatch = Stopwatch.createUnstarted();
    var verificationStopwatch = Stopwatch.createUnstarted();
    for (int i = 0; i < txns.size(); i++) {
        var txn = txns.get(i);
        verificationStopwatch.start();
        var context = new ExecutionContext(txn, permissionLevel, skipAuthorization, sigsLeft);
        final REProcessedTxn processedTxn;
        try {
            processedTxn = this.verify(engineStoreInTransaction, txn, context);
        } catch (TxnParseException | AuthorizationException | ConstraintMachineException e) {
            throw new RadixEngineException(i, txns.size(), txn, e);
        }
        verificationStopwatch.stop();
        // Carry sigs left to the next transaction
        sigsLeft = context.sigsLeft();
        storageStopwatch.start();
        try {
            engineStoreInTransaction.storeTxn(processedTxn);
        } catch (Exception e) {
            logger.error("Store of atom failed: " + processedTxn, e);
            throw e;
        }
        storageStopwatch.stop();
        processedTxns.add(processedTxn);
    }
    try {
        batchVerifier.testMetadata(meta, processedTxns);
    } catch (MetadataException e) {
        logger.error("Invalid metadata: " + processedTxns);
        throw e;
    }
    if (meta != null) {
        engineStoreInTransaction.storeMetadata(meta);
    }
    return RadixEngineResult.create(processedTxns, verificationStopwatch.elapsed(TimeUnit.MILLISECONDS), storageStopwatch.elapsed(TimeUnit.MILLISECONDS));
}
Also used : ConstraintMachineException(com.radixdlt.constraintmachine.exceptions.ConstraintMachineException) ExecutionContext(com.radixdlt.constraintmachine.ExecutionContext) AuthorizationException(com.radixdlt.constraintmachine.exceptions.AuthorizationException) ArrayList(java.util.ArrayList) TxnParseException(com.radixdlt.engine.parser.exceptions.TxnParseException) REProcessedTxn(com.radixdlt.constraintmachine.REProcessedTxn) AuthorizationException(com.radixdlt.constraintmachine.exceptions.AuthorizationException) TxBuilderException(com.radixdlt.atom.TxBuilderException) ConstraintMachineException(com.radixdlt.constraintmachine.exceptions.ConstraintMachineException) TxnParseException(com.radixdlt.engine.parser.exceptions.TxnParseException) DeserializeException(com.radixdlt.serialization.DeserializeException) FeeReserveCompleteException(com.radixdlt.application.system.construction.FeeReserveCompleteException)

Example 2 with TxnParseException

use of com.radixdlt.engine.parser.exceptions.TxnParseException in project radixdlt by radixdlt.

the class KeySignHandler method handleRequest.

@Override
public KeySignResponse handleRequest(KeySignRequest request) throws CoreApiException {
    coreModelMapper.verifyNetwork(request.getNetworkIdentifier());
    var pubKey = coreModelMapper.ecPublicKey(request.getPublicKey());
    if (!self.equals(pubKey)) {
        throw CoreApiException.notSupported(new PublicKeyNotSupportedError().unsupportedPublicKey(request.getPublicKey()).type(PublicKeyNotSupportedError.class.getSimpleName()));
    }
    // Verify this is a valid transaction and not anything more malicious
    var bytes = coreModelMapper.bytes(request.getUnsignedTransaction());
    var txn = Txn.create(bytes);
    try {
        radixEngineProvider.get().getParser().parse(txn);
    } catch (TxnParseException e) {
        throw coreModelMapper.parseException(e);
    }
    var builder = TxLowLevelBuilder.newBuilder(bytes);
    var hash = builder.hashToSign();
    var signature = this.hashSigner.sign(hash);
    var signedTransaction = builder.sig(signature).blob();
    return new KeySignResponse().signedTransaction(Bytes.toHexString(signedTransaction));
}
Also used : TxnParseException(com.radixdlt.engine.parser.exceptions.TxnParseException) PublicKeyNotSupportedError(com.radixdlt.api.core.openapitools.model.PublicKeyNotSupportedError) KeySignResponse(com.radixdlt.api.core.openapitools.model.KeySignResponse)

Example 3 with TxnParseException

use of com.radixdlt.engine.parser.exceptions.TxnParseException in project radixdlt by radixdlt.

the class RadixEngine method executeInternal.

private RadixEngineResult<M> executeInternal(EngineStore.EngineStoreInTransaction<M> engineStoreInTransaction, List<Txn> txns, Optional<M> metaOpt, PermissionLevel permissionLevel, boolean skipAuthorization) throws RadixEngineException {
    var processedTxns = new ArrayList<REProcessedTxn>();
    // FIXME: This is quite the hack to increase sigsLeft for execution on noncommits (e.g. mempool)
    // FIXME: Should probably just change metering
    // Start with 0
    var sigsLeft = metaOpt.isPresent() ? 0 : 1000;
    var storageStopwatch = Stopwatch.createUnstarted();
    var verificationStopwatch = Stopwatch.createUnstarted();
    for (int i = 0; i < txns.size(); i++) {
        var txn = txns.get(i);
        verificationStopwatch.start();
        var context = new ExecutionContext(txn, permissionLevel, skipAuthorization, sigsLeft);
        final REProcessedTxn processedTxn;
        try {
            processedTxn = this.verify(engineStoreInTransaction, txn, context);
        } catch (TxnParseException | AuthorizationException | ConstraintMachineException e) {
            throw new RadixEngineException(i, txns.size(), txn, e);
        }
        verificationStopwatch.stop();
        // Carry sigs left to the next transaction
        sigsLeft = context.sigsLeft();
        storageStopwatch.start();
        try {
            engineStoreInTransaction.storeTxn(processedTxn);
        } catch (Exception e) {
            logger.error("Store of atom failed: " + processedTxn, e);
            throw e;
        }
        storageStopwatch.stop();
        processedTxns.add(processedTxn);
    }
    try {
        final var resultMetadata = metaOpt.map(meta -> {
            final var postProcessedMetadata = postProcessor.process(meta, engineStoreInTransaction, processedTxns);
            engineStoreInTransaction.storeMetadata(postProcessedMetadata);
            return postProcessedMetadata;
        }).orElse(null);
        return RadixEngineResult.create(processedTxns, resultMetadata, verificationStopwatch.elapsed(TimeUnit.MILLISECONDS), storageStopwatch.elapsed(TimeUnit.MILLISECONDS));
    } catch (PostProcessorException e) {
        logger.error("Invalid metadata: " + processedTxns);
        throw e;
    }
}
Also used : SubstateSerialization(com.radixdlt.constraintmachine.SubstateSerialization) TxAction(com.radixdlt.atom.TxAction) BiFunction(java.util.function.BiFunction) TxBuilder(com.radixdlt.atom.TxBuilder) TxnConstructionRequest(com.radixdlt.atom.TxnConstructionRequest) ResourceInBucket(com.radixdlt.application.tokens.ResourceInBucket) VirtualSubstateDeserialization(com.radixdlt.constraintmachine.VirtualSubstateDeserialization) ParsedTxn(com.radixdlt.engine.parser.ParsedTxn) Map(java.util.Map) SystemMapKey(com.radixdlt.constraintmachine.SystemMapKey) AuthorizationException(com.radixdlt.constraintmachine.exceptions.AuthorizationException) Predicate(java.util.function.Predicate) Set(java.util.Set) ExecutionContext(com.radixdlt.constraintmachine.ExecutionContext) REAddr(com.radixdlt.identifiers.REAddr) TxBuilderException(com.radixdlt.atom.TxBuilderException) EngineStore(com.radixdlt.store.EngineStore) Particle(com.radixdlt.constraintmachine.Particle) Objects(java.util.Objects) List(java.util.List) Logger(org.apache.logging.log4j.Logger) ConstraintMachineException(com.radixdlt.constraintmachine.exceptions.ConstraintMachineException) Optional(java.util.Optional) TxnParseException(com.radixdlt.engine.parser.exceptions.TxnParseException) SubstateId(com.radixdlt.atom.SubstateId) UInt384(com.radixdlt.utils.UInt384) Stopwatch(com.google.common.base.Stopwatch) SubstateStore(com.radixdlt.atom.SubstateStore) HashMap(java.util.HashMap) PermissionLevel(com.radixdlt.constraintmachine.PermissionLevel) ECPublicKey(com.radixdlt.crypto.ECPublicKey) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) RawSubstateBytes(com.radixdlt.constraintmachine.RawSubstateBytes) ArrayList(java.util.ArrayList) TransientEngineStore(com.radixdlt.store.TransientEngineStore) SubstateDeserialization(com.radixdlt.constraintmachine.SubstateDeserialization) REParser(com.radixdlt.engine.parser.REParser) UInt256(com.radixdlt.utils.UInt256) REProcessedTxn(com.radixdlt.constraintmachine.REProcessedTxn) SubstateIndex(com.radixdlt.constraintmachine.SubstateIndex) ConstraintMachineConfig(com.radixdlt.constraintmachine.ConstraintMachineConfig) Txn(com.radixdlt.atom.Txn) TimeUnit(java.util.concurrent.TimeUnit) CloseableCursor(com.radixdlt.atom.CloseableCursor) ConstraintMachine(com.radixdlt.constraintmachine.ConstraintMachine) DeserializeException(com.radixdlt.serialization.DeserializeException) FeeReserveCompleteException(com.radixdlt.application.system.construction.FeeReserveCompleteException) LogManager(org.apache.logging.log4j.LogManager) REConstructor(com.radixdlt.atom.REConstructor) AuthorizationException(com.radixdlt.constraintmachine.exceptions.AuthorizationException) ArrayList(java.util.ArrayList) TxnParseException(com.radixdlt.engine.parser.exceptions.TxnParseException) REProcessedTxn(com.radixdlt.constraintmachine.REProcessedTxn) AuthorizationException(com.radixdlt.constraintmachine.exceptions.AuthorizationException) TxBuilderException(com.radixdlt.atom.TxBuilderException) ConstraintMachineException(com.radixdlt.constraintmachine.exceptions.ConstraintMachineException) TxnParseException(com.radixdlt.engine.parser.exceptions.TxnParseException) DeserializeException(com.radixdlt.serialization.DeserializeException) FeeReserveCompleteException(com.radixdlt.application.system.construction.FeeReserveCompleteException) ConstraintMachineException(com.radixdlt.constraintmachine.exceptions.ConstraintMachineException) ExecutionContext(com.radixdlt.constraintmachine.ExecutionContext)

Example 4 with TxnParseException

use of com.radixdlt.engine.parser.exceptions.TxnParseException in project radixdlt by radixdlt.

the class REParser method parse.

public ParsedTxn parse(Txn txn) throws TxnParseException {
    UInt256 feePaid = null;
    ECDSASignature sig = null;
    int sigPosition = 0;
    var parserState = new ParserState(txn);
    var buf = ByteBuffer.wrap(txn.getPayload());
    while (buf.hasRemaining()) {
        if (sig != null) {
            throw new TxnParseException(parserState, "Signature must be last");
        }
        var curPos = buf.position();
        parserState.pos(curPos);
        final var inst = readInstruction(parserState, buf);
        parserState.nextInstruction(inst);
        if (inst.isStateUpdate()) {
            parserState.substateUpdate(inst.getMicroOp().getOp());
        } else if (inst.getMicroOp().getOp() == REOp.READ || inst.getMicroOp().getOp() == REOp.READINDEX) {
            parserState.read();
        } else if (inst.getMicroOp() == REInstruction.REMicroOp.HEADER) {
            parserState.header(inst.getData());
        } else if (inst.getMicroOp() == REInstruction.REMicroOp.SYSCALL) {
            try {
                var callData = inst.<CallData>getData();
                byte id = callData.get(0);
                var syscall = Syscall.of(id).orElseThrow(() -> new TxnParseException(parserState, "Invalid call data type: " + id));
                switch(syscall) {
                    case FEE_RESERVE_PUT:
                        if (feePaid != null) {
                            throw new TxnParseException(parserState, "Should only pay fees once.");
                        }
                        feePaid = callData.getUInt256(1);
                        break;
                    case FEE_RESERVE_TAKE:
                        if (feePaid == null) {
                            throw new TxnParseException(parserState, "No fees paid");
                        }
                        var takeAmount = callData.getUInt256(1);
                        if (takeAmount.compareTo(feePaid) > 0) {
                            throw new TxnParseException(parserState, "Trying to take more fees than paid");
                        }
                        feePaid = feePaid.subtract(takeAmount);
                        break;
                    case READDR_CLAIM:
                        break;
                    // TODO: Along with FeeConstraintScrypt.java
                    default:
                        throw new TxnParseException(parserState, "Invalid call data type: " + id);
                }
            } catch (CallDataAccessException | TrailingBytesException e) {
                throw new TxnParseException(parserState, e);
            }
        } else if (inst.getMicroOp() == REInstruction.REMicroOp.MSG) {
            parserState.msg(inst.getData());
        } else if (inst.getMicroOp() == REInstruction.REMicroOp.END) {
            parserState.end();
        } else if (inst.getMicroOp() == REInstruction.REMicroOp.SIG) {
            sigPosition = curPos;
            sig = inst.getData();
        } else {
            throw new TxnParseException(parserState, "Unknown CM Op " + inst.getMicroOp());
        }
    }
    parserState.finish();
    return new ParsedTxn(txn, feePaid, parserState.instructions, parserState.msg, sig == null ? null : Pair.of(calculatePayloadHash(txn, sigPosition), sig), parserState.disableResourceAllocAndDestroy);
}
Also used : ECDSASignature(com.radixdlt.crypto.ECDSASignature) TxnParseException(com.radixdlt.engine.parser.exceptions.TxnParseException) UInt256(com.radixdlt.utils.UInt256)

Example 5 with TxnParseException

use of com.radixdlt.engine.parser.exceptions.TxnParseException in project radixdlt by radixdlt.

the class TransactionsHandler method construct.

private CommittedTransaction construct(Txn txn, RecoverableProcessedTxn recoveryInfo, AccumulatorState accumulatorState) {
    var parser = radixEngineProvider.get().getParser();
    ParsedTxn parsedTxn;
    try {
        parsedTxn = parser.parse(txn);
    } catch (TxnParseException e) {
        throw new IllegalStateException("Could not parse already committed transaction", e);
    }
    var committedTransaction = new CommittedTransaction();
    recoveryInfo.recoverStateUpdates(parsedTxn).stream().map(stateUpdateGroup -> {
        var operationGroup = new OperationGroup();
        stateUpdateGroup.stream().map(stateUpdate -> {
            var substateOperation = stateUpdate.recover(radixEngineProvider);
            return coreModelMapper.operation(substateOperation.getSubstate(), substateOperation.getSubstateId(), substateOperation.isBootUp(), this::symbol);
        }).forEach(operationGroup::addOperationsItem);
        return operationGroup;
    }).forEach(committedTransaction::addOperationGroupsItem);
    var signedBy = parsedTxn.getPayloadHashAndSig().map(hashAndSig -> {
        var hash = hashAndSig.getFirst();
        var sig = hashAndSig.getSecond();
        return ECPublicKey.recoverFrom(hash, sig).orElseThrow(() -> new IllegalStateException("Invalid signature on already committed transaction"));
    });
    var transactionIdentifier = coreModelMapper.transactionIdentifier(txn.getId());
    return committedTransaction.committedStateIdentifier(coreModelMapper.stateIdentifier(accumulatorState)).metadata(new CommittedTransactionMetadata().fee(coreModelMapper.nativeTokenAmount(parsedTxn.getFeePaid())).message(parsedTxn.getMsg().map(Bytes::toHexString).orElse(null)).size(txn.getPayload().length).hex(Bytes.toHexString(txn.getPayload())).signedBy(signedBy.map(coreModelMapper::publicKey).orElse(null))).transactionIdentifier(transactionIdentifier);
}
Also used : SubstateTypeId(com.radixdlt.atom.SubstateTypeId) LedgerAndBFTProof(com.radixdlt.statecomputer.LedgerAndBFTProof) Inject(com.google.inject.Inject) RecoverableProcessedTxn(com.radixdlt.api.core.reconstruction.RecoverableProcessedTxn) StateIdentifier(com.radixdlt.api.core.openapitools.model.StateIdentifier) ECPublicKey(com.radixdlt.crypto.ECPublicKey) OperationGroup(com.radixdlt.api.core.openapitools.model.OperationGroup) ParsedTxn(com.radixdlt.engine.parser.ParsedTxn) CommittedTransaction(com.radixdlt.api.core.openapitools.model.CommittedTransaction) CoreJsonRpcHandler(com.radixdlt.api.core.CoreJsonRpcHandler) BerkeleyLedgerEntryStore(com.radixdlt.store.berkeley.BerkeleyLedgerEntryStore) SystemMapKey(com.radixdlt.constraintmachine.SystemMapKey) AccumulatorState(com.radixdlt.ledger.AccumulatorState) BerkeleyRecoverableProcessedTxnStore(com.radixdlt.api.core.reconstruction.BerkeleyRecoverableProcessedTxnStore) CoreModelMapper(com.radixdlt.api.core.model.CoreModelMapper) TokenResourceMetadata(com.radixdlt.application.tokens.state.TokenResourceMetadata) CoreApiException(com.radixdlt.api.core.model.CoreApiException) RadixEngine(com.radixdlt.engine.RadixEngine) Txn(com.radixdlt.atom.Txn) REAddr(com.radixdlt.identifiers.REAddr) CommittedTransactionsRequest(com.radixdlt.api.core.openapitools.model.CommittedTransactionsRequest) Provider(com.google.inject.Provider) Bytes(com.radixdlt.utils.Bytes) CommittedTransactionMetadata(com.radixdlt.api.core.openapitools.model.CommittedTransactionMetadata) CommittedTransactionsResponse(com.radixdlt.api.core.openapitools.model.CommittedTransactionsResponse) TxnParseException(com.radixdlt.engine.parser.exceptions.TxnParseException) LedgerAccumulator(com.radixdlt.ledger.LedgerAccumulator) OperationGroup(com.radixdlt.api.core.openapitools.model.OperationGroup) TxnParseException(com.radixdlt.engine.parser.exceptions.TxnParseException) CommittedTransactionMetadata(com.radixdlt.api.core.openapitools.model.CommittedTransactionMetadata) CommittedTransaction(com.radixdlt.api.core.openapitools.model.CommittedTransaction) ParsedTxn(com.radixdlt.engine.parser.ParsedTxn)

Aggregations

TxnParseException (com.radixdlt.engine.parser.exceptions.TxnParseException)5 FeeReserveCompleteException (com.radixdlt.application.system.construction.FeeReserveCompleteException)2 TxBuilderException (com.radixdlt.atom.TxBuilderException)2 Txn (com.radixdlt.atom.Txn)2 ExecutionContext (com.radixdlt.constraintmachine.ExecutionContext)2 REProcessedTxn (com.radixdlt.constraintmachine.REProcessedTxn)2 SystemMapKey (com.radixdlt.constraintmachine.SystemMapKey)2 AuthorizationException (com.radixdlt.constraintmachine.exceptions.AuthorizationException)2 ConstraintMachineException (com.radixdlt.constraintmachine.exceptions.ConstraintMachineException)2 ECPublicKey (com.radixdlt.crypto.ECPublicKey)2 ParsedTxn (com.radixdlt.engine.parser.ParsedTxn)2 REAddr (com.radixdlt.identifiers.REAddr)2 DeserializeException (com.radixdlt.serialization.DeserializeException)2 UInt256 (com.radixdlt.utils.UInt256)2 ArrayList (java.util.ArrayList)2 Stopwatch (com.google.common.base.Stopwatch)1 Inject (com.google.inject.Inject)1 Provider (com.google.inject.Provider)1 CoreJsonRpcHandler (com.radixdlt.api.core.CoreJsonRpcHandler)1 CoreApiException (com.radixdlt.api.core.model.CoreApiException)1