Search in sources :

Example 1 with ProcedureException

use of com.radixdlt.constraintmachine.exceptions.ProcedureException in project radixdlt by radixdlt.

the class EpochUpdateConstraintScrypt method epochUpdate.

private void epochUpdate(Loader os) {
    // Epoch Update
    os.procedure(new DownProcedure<>(EndPrevRound.class, EpochData.class, d -> new Authorization(PermissionLevel.SUPER_USER, (r, c) -> {
    }), (d, s, r, c) -> {
        // TODO: Should move this authorization instead of checking epoch > 0
        if (d.epoch() > 0 && s.getClosedRound().view() != maxRounds) {
            throw new ProcedureException("Must execute epoch update on end of round " + maxRounds + " but is " + s.getClosedRound().view());
        }
        return ReducerResult.incomplete(new UpdatingEpoch(d));
    }));
    os.procedure(new ShutdownAllProcedure<>(ExitingStake.class, UpdatingEpoch.class, () -> new Authorization(PermissionLevel.SUPER_USER, (r, c) -> {
    }), (s, d, c, r) -> {
        var exittingStake = new ProcessExittingStake(s);
        return ReducerResult.incomplete(exittingStake.process(d));
    }));
    os.procedure(new UpProcedure<>(ProcessExittingStake.class, TokensInAccount.class, u -> new Authorization(PermissionLevel.SUPER_USER, (r, c) -> {
    }), (s, u, c, r) -> ReducerResult.incomplete(s.unlock(u))));
    os.procedure(new ShutdownAllProcedure<>(ValidatorBFTData.class, RewardingValidators.class, () -> new Authorization(PermissionLevel.SUPER_USER, (r, c) -> {
    }), (s, d, c, r) -> ReducerResult.incomplete(s.process(d, c))));
    os.procedure(new ShutdownAllProcedure<>(PreparedUnstakeOwnership.class, PreparingUnstake.class, () -> new Authorization(PermissionLevel.SUPER_USER, (r, c) -> {
    }), (s, d, c, r) -> ReducerResult.incomplete(s.unstakes(d))));
    os.procedure(new DownProcedure<>(LoadingStake.class, ValidatorStakeData.class, d -> d.bucket().withdrawAuthorization(), (d, s, r, c) -> ReducerResult.incomplete(s.startUpdate(d))));
    os.procedure(new UpProcedure<>(Unstaking.class, ExitingStake.class, u -> new Authorization(PermissionLevel.SUPER_USER, (r, c) -> {
    }), (s, u, c, r) -> ReducerResult.incomplete(s.exit(u))));
    os.procedure(new ShutdownAllProcedure<>(PreparedStake.class, PreparingStake.class, () -> new Authorization(PermissionLevel.SUPER_USER, (r, c) -> {
    }), (s, d, c, r) -> ReducerResult.incomplete(s.prepareStakes(d))));
    os.procedure(new ShutdownAllProcedure<>(ValidatorFeeCopy.class, PreparingRakeUpdate.class, () -> new Authorization(PermissionLevel.SUPER_USER, (r, c) -> {
    }), (s, d, c, r) -> ReducerResult.incomplete(s.prepareRakeUpdates(d))));
    os.procedure(new UpProcedure<>(ResetRakeUpdate.class, ValidatorFeeCopy.class, u -> new Authorization(PermissionLevel.SUPER_USER, (r, c) -> {
    }), (s, u, c, r) -> ReducerResult.incomplete(s.reset(u))));
    os.procedure(new ShutdownAllProcedure<>(ValidatorOwnerCopy.class, PreparingOwnerUpdate.class, () -> new Authorization(PermissionLevel.SUPER_USER, (r, c) -> {
    }), (s, d, c, r) -> ReducerResult.incomplete(s.prepareValidatorUpdate(d))));
    os.procedure(new UpProcedure<>(ResetOwnerUpdate.class, ValidatorOwnerCopy.class, u -> new Authorization(PermissionLevel.SUPER_USER, (r, c) -> {
    }), (s, u, c, r) -> ReducerResult.incomplete(s.reset(u))));
    os.procedure(new ShutdownAllProcedure<>(ValidatorRegisteredCopy.class, PreparingRegisteredUpdate.class, () -> new Authorization(PermissionLevel.SUPER_USER, (r, c) -> {
    }), (s, d, c, r) -> ReducerResult.incomplete(s.prepareRegisterUpdates(d))));
    os.procedure(new UpProcedure<>(ResetRegisteredUpdate.class, ValidatorRegisteredCopy.class, u -> new Authorization(PermissionLevel.SUPER_USER, (r, c) -> {
    }), (s, u, c, r) -> ReducerResult.incomplete(s.reset(u))));
    os.procedure(new UpProcedure<>(Staking.class, StakeOwnership.class, u -> new Authorization(PermissionLevel.SUPER_USER, (r, c) -> {
    }), (s, u, c, r) -> ReducerResult.incomplete(s.stake(u))));
    os.procedure(new UpProcedure<>(UpdatingValidatorStakes.class, ValidatorStakeData.class, u -> new Authorization(PermissionLevel.SUPER_USER, (r, c) -> {
    }), (s, u, c, r) -> ReducerResult.incomplete(s.updateStake(u))));
    os.procedure(new ReadIndexProcedure<>(CreatingNextValidatorSet.class, ValidatorStakeData.class, () -> new Authorization(PermissionLevel.SUPER_USER, (r, c) -> {
    }), (s, d, c, r) -> ReducerResult.incomplete(s.readIndex(d, c))));
    os.procedure(new UpProcedure<>(BootupValidator.class, ValidatorBFTData.class, u -> new Authorization(PermissionLevel.SUPER_USER, (r, c) -> {
    }), (s, u, c, r) -> ReducerResult.incomplete(s.bootUp(u))));
    os.procedure(new UpProcedure<>(StartingNextEpoch.class, EpochData.class, u -> new Authorization(PermissionLevel.SUPER_USER, (r, c) -> {
    }), (s, u, c, r) -> ReducerResult.incomplete(s.nextEpoch(u))));
    os.procedure(new UpProcedure<>(StartingEpochRound.class, RoundData.class, u -> new Authorization(PermissionLevel.SUPER_USER, (r, c) -> {
    }), (s, u, c, r) -> {
        if (u.view() != 0) {
            throw new ProcedureException("Epoch must start with view 0");
        }
        return ReducerResult.complete();
    }));
}
Also used : SubstateTypeId(com.radixdlt.atom.SubstateTypeId) java.util(java.util) StakeOwnership(com.radixdlt.application.system.state.StakeOwnership) PreparedUnstakeOwnership(com.radixdlt.application.tokens.state.PreparedUnstakeOwnership) ValidatorStakeData(com.radixdlt.application.system.state.ValidatorStakeData) NextValidatorSetEvent(com.radixdlt.constraintmachine.REEvent.NextValidatorSetEvent) ValidatorRegisteredCopy(com.radixdlt.application.validators.state.ValidatorRegisteredCopy) MismatchException(com.radixdlt.constraintmachine.exceptions.MismatchException) HasEpochData(com.radixdlt.application.system.state.HasEpochData) ExitingStake(com.radixdlt.application.tokens.state.ExitingStake) SubstateDefinition(com.radixdlt.atomos.SubstateDefinition) ECPublicKey(com.radixdlt.crypto.ECPublicKey) Function(java.util.function.Function) Supplier(java.util.function.Supplier) RoundData(com.radixdlt.application.system.state.RoundData) Longs(com.radixdlt.utils.Longs) ConstraintScrypt(com.radixdlt.atomos.ConstraintScrypt) ValidatorOwnerCopy(com.radixdlt.application.validators.state.ValidatorOwnerCopy) ProcedureException(com.radixdlt.constraintmachine.exceptions.ProcedureException) EpochData(com.radixdlt.application.system.state.EpochData) ValidatorBFTData(com.radixdlt.application.system.state.ValidatorBFTData) UInt256(com.radixdlt.utils.UInt256) UnsignedBytes(com.google.common.primitives.UnsignedBytes) PreparedStake(com.radixdlt.application.tokens.state.PreparedStake) Loader(com.radixdlt.atomos.Loader) REFieldSerialization(com.radixdlt.atom.REFieldSerialization) TokensInAccount(com.radixdlt.application.tokens.state.TokensInAccount) REAddr(com.radixdlt.identifiers.REAddr) Streams(com.google.common.collect.Streams) Collectors(java.util.stream.Collectors) com.radixdlt.constraintmachine(com.radixdlt.constraintmachine) RAKE_MAX(com.radixdlt.application.validators.scrypt.ValidatorUpdateRakeConstraintScrypt.RAKE_MAX) ValidatorFeeCopy(com.radixdlt.application.validators.state.ValidatorFeeCopy) KeyComparator(com.radixdlt.utils.KeyComparator) ValidatorBFTDataEvent(com.radixdlt.constraintmachine.REEvent.ValidatorBFTDataEvent) StakeOwnership(com.radixdlt.application.system.state.StakeOwnership) PreparedStake(com.radixdlt.application.tokens.state.PreparedStake) PreparedUnstakeOwnership(com.radixdlt.application.tokens.state.PreparedUnstakeOwnership) ProcedureException(com.radixdlt.constraintmachine.exceptions.ProcedureException) HasEpochData(com.radixdlt.application.system.state.HasEpochData) EpochData(com.radixdlt.application.system.state.EpochData) RoundData(com.radixdlt.application.system.state.RoundData) ValidatorBFTData(com.radixdlt.application.system.state.ValidatorBFTData) ValidatorRegisteredCopy(com.radixdlt.application.validators.state.ValidatorRegisteredCopy) ValidatorStakeData(com.radixdlt.application.system.state.ValidatorStakeData) ValidatorOwnerCopy(com.radixdlt.application.validators.state.ValidatorOwnerCopy) TokensInAccount(com.radixdlt.application.tokens.state.TokensInAccount) ExitingStake(com.radixdlt.application.tokens.state.ExitingStake) ValidatorFeeCopy(com.radixdlt.application.validators.state.ValidatorFeeCopy)

Example 2 with ProcedureException

use of com.radixdlt.constraintmachine.exceptions.ProcedureException in project radixdlt by radixdlt.

the class TokensConstraintScryptV3 method defineTokenCreation.

private void defineTokenCreation(Loader os) {
    os.procedure(new UpProcedure<>(SystemConstraintScrypt.REAddrClaim.class, TokenResource.class, u -> new Authorization(PermissionLevel.USER, (r, c) -> {
    }), (s, u, c, r) -> {
        if (!u.addr().equals(s.getAddr())) {
            throw new ProcedureException("Addresses don't match");
        }
        var str = new String(s.getArg());
        if (reservedSymbols.contains(str) && c.permissionLevel() != PermissionLevel.SYSTEM) {
            throw new ReservedSymbolException(str);
        }
        if (!tokenSymbolPattern.matcher(str).matches()) {
            throw new ProcedureException("invalid token symbol: " + str);
        }
        if (u.isMutable()) {
            return ReducerResult.incomplete(new NeedMetadata(s.getArg(), u));
        }
        if (!u.granularity().equals(UInt256.ONE)) {
            throw new ProcedureException("Granularity must be one.");
        }
        return ReducerResult.incomplete(new NeedFixedTokenSupply(s.getArg(), u));
    }));
    os.procedure(new UpProcedure<>(NeedFixedTokenSupply.class, TokensInAccount.class, u -> new Authorization(PermissionLevel.USER, (r, c) -> {
    }), (s, u, c, r) -> {
        if (!u.resourceAddr().equals(s.tokenResource.addr())) {
            throw new ProcedureException("Addresses don't match.");
        }
        return ReducerResult.incomplete(new NeedMetadata(s.arg, s.tokenResource));
    }));
    os.procedure(new UpProcedure<>(NeedMetadata.class, TokenResourceMetadata.class, u -> new Authorization(PermissionLevel.USER, (r, c) -> {
    }), (s, u, c, r) -> {
        s.metadata(u, c);
        return ReducerResult.complete();
    }));
}
Also used : SubstateTypeId(com.radixdlt.atom.SubstateTypeId) TokenResourceMetadata(com.radixdlt.application.tokens.state.TokenResourceMetadata) Loader(com.radixdlt.atomos.Loader) REFieldSerialization(com.radixdlt.atom.REFieldSerialization) TokenResource(com.radixdlt.application.tokens.state.TokenResource) Set(java.util.Set) TokensInAccount(com.radixdlt.application.tokens.state.TokensInAccount) SubstateDefinition(com.radixdlt.atomos.SubstateDefinition) StandardCharsets(java.nio.charset.StandardCharsets) com.radixdlt.constraintmachine(com.radixdlt.constraintmachine) ResourceCreatedEvent(com.radixdlt.constraintmachine.REEvent.ResourceCreatedEvent) ReservedSymbolException(com.radixdlt.constraintmachine.exceptions.ReservedSymbolException) SystemConstraintScrypt(com.radixdlt.application.system.scrypt.SystemConstraintScrypt) ConstraintScrypt(com.radixdlt.atomos.ConstraintScrypt) ProcedureException(com.radixdlt.constraintmachine.exceptions.ProcedureException) Pattern(java.util.regex.Pattern) DeserializeException(com.radixdlt.serialization.DeserializeException) UInt256(com.radixdlt.utils.UInt256) TokenResource(com.radixdlt.application.tokens.state.TokenResource) TokenResourceMetadata(com.radixdlt.application.tokens.state.TokenResourceMetadata) ReservedSymbolException(com.radixdlt.constraintmachine.exceptions.ReservedSymbolException) TokensInAccount(com.radixdlt.application.tokens.state.TokensInAccount) ProcedureException(com.radixdlt.constraintmachine.exceptions.ProcedureException)

Example 3 with ProcedureException

use of com.radixdlt.constraintmachine.exceptions.ProcedureException in project radixdlt by radixdlt.

the class ConstraintMachine method statefulVerify.

/**
 * Executes transition procedures and witness validators in a particle group and validates that
 * the particle group is well formed.
 */
List<List<REStateUpdate>> statefulVerify(ExecutionContext context, CMValidationState validationState, List<REInstruction> instructions) throws ConstraintMachineException {
    int instIndex = 0;
    var expectEnd = false;
    ReducerState reducerState = null;
    var readableAddrs = validationState.resources();
    var groupedStateUpdates = new ArrayList<List<REStateUpdate>>();
    var stateUpdates = new ArrayList<REStateUpdate>();
    meter.onStart(context);
    for (REInstruction inst : instructions) {
        try {
            if (expectEnd && inst.getMicroOp() != REInstruction.REMicroOp.END) {
                throw new MissingExpectedEndException();
            }
            if (inst.getMicroOp() == REInstruction.REMicroOp.SYSCALL) {
                CallData callData = inst.getData();
                var opSignature = OpSignature.ofMethod(inst.getMicroOp().getOp(), REAddr.ofSystem());
                var methodProcedure = loadProcedure(reducerState, opSignature);
                reducerState = callProcedure(methodProcedure, callData, reducerState, readableAddrs, context);
            } else if (inst.getMicroOp().getOp() == REOp.READ) {
                final Particle nextParticle;
                if (inst.getMicroOp() == REInstruction.REMicroOp.VREAD) {
                    SubstateId substateId = inst.getData();
                    nextParticle = validationState.virtualRead(substateId);
                } else if (inst.getMicroOp() == REInstruction.REMicroOp.READ) {
                    SubstateId substateId = inst.getData();
                    nextParticle = validationState.read(substateId);
                } else if (inst.getMicroOp() == REInstruction.REMicroOp.LREAD) {
                    SubstateId substateId = inst.getData();
                    nextParticle = validationState.localRead(substateId.getIndex().orElseThrow());
                } else if (inst.getMicroOp() == REInstruction.REMicroOp.LVREAD) {
                    SubstateId substateId = inst.getData();
                    nextParticle = validationState.localVirtualRead(substateId);
                } else {
                    throw new IllegalStateException("Unknown read op " + inst.getMicroOp());
                }
                var eventId = OpSignature.ofSubstateUpdate(inst.getMicroOp().getOp(), nextParticle.getClass());
                var methodProcedure = loadProcedure(reducerState, eventId);
                reducerState = callProcedure(methodProcedure, nextParticle, reducerState, readableAddrs, context);
                expectEnd = reducerState == null;
            } else if (inst.getMicroOp().getOp() == REOp.DOWNINDEX || inst.getMicroOp().getOp() == REOp.READINDEX) {
                byte[] raw = inst.getData();
                var index = SubstateIndex.create(raw, validationState.deserialization.byteToClass(raw[0]));
                var substateCursor = validationState.getIndexedCursor(index);
                var tmp = stateUpdates;
                final int tmpInstIndex = instIndex;
                var iterator = new Iterator<Particle>() {

                    @Override
                    public boolean hasNext() {
                        return substateCursor.hasNext();
                    }

                    @Override
                    public Particle next() {
                        // FIXME: this is a hack
                        // FIXME: do this via shutdownAll state update rather than individually
                        var substate = substateCursor.next();
                        if (inst.getMicroOp().getOp() == REOp.DOWNINDEX) {
                            var typeByte = deserialization.classToByte(substate.getParticle().getClass());
                            tmp.add(REStateUpdate.of(REOp.DOWN, tmpInstIndex, substate.getId(), typeByte, substate.getParticle(), null));
                        }
                        return substate.getParticle();
                    }
                };
                var substateIterator = new IndexedSubstateIterator<>(index, iterator);
                try {
                    var eventId = OpSignature.ofSubstateUpdate(inst.getMicroOp().getOp(), index.getSubstateClass());
                    var methodProcedure = loadProcedure(reducerState, eventId);
                    reducerState = callProcedure(methodProcedure, substateIterator, reducerState, readableAddrs, context);
                } finally {
                    substateCursor.close();
                }
            } else if (inst.isStateUpdate()) {
                final SubstateId substateId;
                final Particle nextParticle;
                final Supplier<ByteBuffer> substateBuffer;
                if (inst.getMicroOp() == REInstruction.REMicroOp.UP) {
                    // TODO: Cleanup indexing of substate class
                    UpSubstate upSubstate = inst.getData();
                    var buf = upSubstate.getSubstateBuffer();
                    nextParticle = validationState.deserialization.deserialize(buf);
                    if (buf.hasRemaining()) {
                        throw new TrailingBytesException("Substate has trailing bytes.");
                    }
                    substateId = upSubstate.getSubstateId();
                    substateBuffer = upSubstate::getSubstateBuffer;
                    validationState.bootUp(Substate.create(nextParticle, substateId), upSubstate::getSubstateBuffer);
                } else if (inst.getMicroOp() == REInstruction.REMicroOp.VDOWN) {
                    substateId = inst.getData();
                    substateBuffer = null;
                    nextParticle = validationState.virtualShutdown(substateId);
                } else if (inst.getMicroOp() == REInstruction.REMicroOp.DOWN) {
                    substateId = inst.getData();
                    substateBuffer = null;
                    nextParticle = validationState.shutdown(substateId);
                } else if (inst.getMicroOp() == REInstruction.REMicroOp.LDOWN) {
                    substateId = inst.getData();
                    substateBuffer = null;
                    nextParticle = validationState.localShutdown(substateId.getIndex().orElseThrow());
                } else if (inst.getMicroOp() == REInstruction.REMicroOp.LVDOWN) {
                    substateId = inst.getData();
                    substateBuffer = null;
                    nextParticle = validationState.localVirtualShutdown(substateId);
                } else {
                    throw new IllegalStateException("Unhandled op: " + inst.getMicroOp());
                }
                var op = inst.getMicroOp().getOp();
                var typeByte = deserialization.classToByte(nextParticle.getClass());
                stateUpdates.add(REStateUpdate.of(op, instIndex, substateId, typeByte, nextParticle, substateBuffer));
                var eventId = OpSignature.ofSubstateUpdate(op, nextParticle.getClass());
                var methodProcedure = loadProcedure(reducerState, eventId);
                reducerState = callProcedure(methodProcedure, nextParticle, reducerState, readableAddrs, context);
                expectEnd = reducerState == null;
            } else if (inst.getMicroOp() == REInstruction.REMicroOp.END) {
                groupedStateUpdates.add(stateUpdates);
                stateUpdates = new ArrayList<>();
                if (reducerState != null) {
                    var eventId = OpSignature.ofSubstateUpdate(inst.getMicroOp().getOp(), null);
                    var methodProcedure = loadProcedure(reducerState, eventId);
                    reducerState = callProcedure(methodProcedure, reducerState, reducerState, readableAddrs, context);
                }
                expectEnd = false;
            } else if (inst.getMicroOp() == REInstruction.REMicroOp.SIG) {
                if (context.permissionLevel() != PermissionLevel.SYSTEM) {
                    meter.onSigInstruction(context);
                }
            } else {
                // Collect no-ops here
                if (inst.getMicroOp() != REInstruction.REMicroOp.MSG && inst.getMicroOp() != REInstruction.REMicroOp.HEADER) {
                    throw new ProcedureException("Unknown op " + inst.getMicroOp());
                }
            }
        } catch (Exception e) {
            throw new ConstraintMachineException(instIndex, instructions, reducerState, e);
        }
        instIndex++;
    }
    try {
        context.destroy();
    } catch (Exception e) {
        throw new ConstraintMachineException(instIndex, instructions, reducerState, e);
    }
    return groupedStateUpdates;
}
Also used : ArrayList(java.util.ArrayList) MeterException(com.radixdlt.constraintmachine.exceptions.MeterException) ProcedureException(com.radixdlt.constraintmachine.exceptions.ProcedureException) MissingProcedureException(com.radixdlt.constraintmachine.exceptions.MissingProcedureException) AuthorizationException(com.radixdlt.constraintmachine.exceptions.AuthorizationException) SignedSystemException(com.radixdlt.constraintmachine.exceptions.SignedSystemException) SubstateNotFoundException(com.radixdlt.constraintmachine.exceptions.SubstateNotFoundException) NotAResourceException(com.radixdlt.constraintmachine.exceptions.NotAResourceException) VirtualSubstateAlreadyDownException(com.radixdlt.constraintmachine.exceptions.VirtualSubstateAlreadyDownException) ConstraintMachineException(com.radixdlt.constraintmachine.exceptions.ConstraintMachineException) LocalSubstateNotFoundException(com.radixdlt.constraintmachine.exceptions.LocalSubstateNotFoundException) TrailingBytesException(com.radixdlt.engine.parser.exceptions.TrailingBytesException) InvalidPermissionException(com.radixdlt.constraintmachine.exceptions.InvalidPermissionException) TxnParseException(com.radixdlt.engine.parser.exceptions.TxnParseException) DeserializeException(com.radixdlt.serialization.DeserializeException) ConstraintMachineException(com.radixdlt.constraintmachine.exceptions.ConstraintMachineException) TrailingBytesException(com.radixdlt.engine.parser.exceptions.TrailingBytesException) Iterator(java.util.Iterator) SubstateId(com.radixdlt.atom.SubstateId) Supplier(java.util.function.Supplier) ProcedureException(com.radixdlt.constraintmachine.exceptions.ProcedureException) MissingProcedureException(com.radixdlt.constraintmachine.exceptions.MissingProcedureException)

Example 4 with ProcedureException

use of com.radixdlt.constraintmachine.exceptions.ProcedureException in project radixdlt by radixdlt.

the class SystemConstraintScrypt method main.

@Override
public void main(Loader os) {
    os.substate(VirtualParent.SUBSTATE_DEFINITION);
    // TODO: Down singleton
    os.procedure(new UpProcedure<>(VoidReducerState.class, VirtualParent.class, u -> new Authorization(PermissionLevel.SYSTEM, (r, c) -> {
    }), (s, u, c, r) -> {
        if (u.data().length != 1) {
            throw new ProcedureException("Invalid data: " + Bytes.toHexString(u.data()));
        }
        if (u.data()[0] != SubstateTypeId.UNCLAIMED_READDR.id()) {
            throw new ProcedureException("Invalid data: " + Bytes.toHexString(u.data()));
        }
        return ReducerResult.complete();
    }));
    os.substate(EpochData.SUBSTATE_DEFINITION);
    os.substate(RoundData.SUBSTATE_DEFINITION);
    os.procedure(new SystemCallProcedure<>(TokenHoldingBucket.class, REAddr.ofSystem(), () -> new Authorization(PermissionLevel.USER, (r, c) -> {
    }), (s, d, c) -> {
        var id = d.get(0);
        var syscall = Syscall.of(id).orElseThrow(() -> new ProcedureException("Invalid call type " + id));
        if (syscall != Syscall.FEE_RESERVE_PUT) {
            throw new ProcedureException("Invalid call type: " + syscall);
        }
        var amt = d.getUInt256(1);
        var tokens = s.withdraw(REAddr.ofNativeToken(), amt);
        c.depositFeeReserve(tokens);
        return ReducerResult.incomplete(s);
    }));
    os.procedure(new SystemCallProcedure<>(VoidReducerState.class, REAddr.ofSystem(), () -> new Authorization(PermissionLevel.USER, (r, c) -> {
    }), (s, d, c) -> {
        var id = d.get(0);
        var syscall = Syscall.of(id).orElseThrow(() -> new ProcedureException("Invalid call type " + id));
        if (syscall == Syscall.FEE_RESERVE_TAKE) {
            var amt = d.getUInt256(1);
            var tokens = c.withdrawFeeReserve(amt);
            return ReducerResult.incomplete(new TokenHoldingBucket(tokens));
        } else if (syscall == Syscall.READDR_CLAIM) {
            var bytes = d.getRemainingBytes(1);
            if (bytes.length > MAX_SYMBOL_LENGTH) {
                throw new ProcedureException("Address claim too large.");
            }
            return ReducerResult.incomplete(new REAddrClaimStart(bytes));
        } else {
            throw new ProcedureException("Invalid call type: " + syscall);
        }
    }));
    // PUB_KEY type is already claimed by accounts
    os.substate(UnclaimedREAddr.SUBSTATE_DEFINITION);
    os.procedure(new DownProcedure<>(REAddrClaimStart.class, UnclaimedREAddr.class, d -> {
        final PermissionLevel permissionLevel;
        if (d.addr().isNativeToken() || d.addr().isSystem()) {
            permissionLevel = PermissionLevel.SYSTEM;
        } else {
            permissionLevel = PermissionLevel.USER;
        }
        return new Authorization(permissionLevel, (r, ctx) -> {
        });
    }, (d, s, r, c) -> ReducerResult.incomplete(s.claim(d, c))));
    // For Mainnet Genesis
    os.procedure(new UpProcedure<>(SystemConstraintScrypt.REAddrClaim.class, EpochData.class, u -> new Authorization(PermissionLevel.SYSTEM, (r, c) -> {
    }), (s, u, c, r) -> {
        if (u.epoch() != 0) {
            throw new ProcedureException("First epoch must be 0.");
        }
        return ReducerResult.incomplete(new AllocatingSystem());
    }));
    os.procedure(new UpProcedure<>(AllocatingSystem.class, RoundData.class, u -> new Authorization(PermissionLevel.SYSTEM, (r, c) -> {
    }), (s, u, c, r) -> {
        if (u.view() != 0) {
            throw new ProcedureException("First view must be 0.");
        }
        return ReducerResult.incomplete(new AllocatingVirtualState());
    }));
    os.procedure(new UpProcedure<>(AllocatingVirtualState.class, VirtualParent.class, u -> new Authorization(PermissionLevel.SYSTEM, (r, c) -> {
    }), (s, u, c, r) -> {
        var next = s.createVirtualSubstate(u);
        return next == null ? ReducerResult.complete() : ReducerResult.incomplete(next);
    }));
}
Also used : SubstateTypeId(com.radixdlt.atom.SubstateTypeId) ReducerResult(com.radixdlt.constraintmachine.ReducerResult) Arrays(java.util.Arrays) VoidReducerState(com.radixdlt.constraintmachine.VoidReducerState) Loader(com.radixdlt.atomos.Loader) ReducerState(com.radixdlt.constraintmachine.ReducerState) Authorization(com.radixdlt.constraintmachine.Authorization) ExecutionContext(com.radixdlt.constraintmachine.ExecutionContext) PermissionLevel(com.radixdlt.constraintmachine.PermissionLevel) REAddr(com.radixdlt.identifiers.REAddr) SystemCallProcedure(com.radixdlt.constraintmachine.SystemCallProcedure) RoundData(com.radixdlt.application.system.state.RoundData) VirtualParent(com.radixdlt.application.system.state.VirtualParent) InvalidHashedKeyException(com.radixdlt.constraintmachine.exceptions.InvalidHashedKeyException) Bytes(com.radixdlt.utils.Bytes) UpProcedure(com.radixdlt.constraintmachine.UpProcedure) TokenHoldingBucket(com.radixdlt.application.tokens.scrypt.TokenHoldingBucket) UnclaimedREAddr(com.radixdlt.application.system.state.UnclaimedREAddr) ConstraintScrypt(com.radixdlt.atomos.ConstraintScrypt) DownProcedure(com.radixdlt.constraintmachine.DownProcedure) ProcedureException(com.radixdlt.constraintmachine.exceptions.ProcedureException) LinkedList(java.util.LinkedList) EpochData(com.radixdlt.application.system.state.EpochData) EpochData(com.radixdlt.application.system.state.EpochData) VoidReducerState(com.radixdlt.constraintmachine.VoidReducerState) RoundData(com.radixdlt.application.system.state.RoundData) UnclaimedREAddr(com.radixdlt.application.system.state.UnclaimedREAddr) PermissionLevel(com.radixdlt.constraintmachine.PermissionLevel) TokenHoldingBucket(com.radixdlt.application.tokens.scrypt.TokenHoldingBucket) Authorization(com.radixdlt.constraintmachine.Authorization) ProcedureException(com.radixdlt.constraintmachine.exceptions.ProcedureException) VirtualParent(com.radixdlt.application.system.state.VirtualParent)

Example 5 with ProcedureException

use of com.radixdlt.constraintmachine.exceptions.ProcedureException in project radixdlt by radixdlt.

the class ConstraintMachine method callProcedure.

/**
 * Executes a transition procedure given the next spun particle and a current validation state.
 */
private ReducerState callProcedure(Procedure procedure, Object procedureParam, ReducerState reducerState, Resources immutableAddrs, ExecutionContext context) throws SignedSystemException, InvalidPermissionException, AuthorizationException, MeterException, ProcedureException {
    // System permissions don't require additional authorization
    var authorization = procedure.authorization(procedureParam);
    var requiredLevel = authorization.permissionLevel();
    context.verifyPermissionLevel(requiredLevel);
    if (context.permissionLevel() != PermissionLevel.SYSTEM) {
        try {
            if (requiredLevel == PermissionLevel.USER) {
                this.meter.onUserProcedure(procedure.key(), procedureParam, context);
            } else if (requiredLevel == PermissionLevel.SUPER_USER) {
                this.meter.onSuperUserProcedure(procedure.key(), procedureParam, context);
            }
        } catch (Exception e) {
            throw new MeterException(e);
        }
        if (!context.skipAuthorization()) {
            try {
                authorization.authorizer().verify(immutableAddrs, context);
            } catch (Exception e) {
                throw new AuthorizationException(e);
            }
        }
    }
    return procedure.call(procedureParam, reducerState, immutableAddrs, context).state();
}
Also used : MeterException(com.radixdlt.constraintmachine.exceptions.MeterException) AuthorizationException(com.radixdlt.constraintmachine.exceptions.AuthorizationException) MeterException(com.radixdlt.constraintmachine.exceptions.MeterException) ProcedureException(com.radixdlt.constraintmachine.exceptions.ProcedureException) MissingProcedureException(com.radixdlt.constraintmachine.exceptions.MissingProcedureException) AuthorizationException(com.radixdlt.constraintmachine.exceptions.AuthorizationException) SignedSystemException(com.radixdlt.constraintmachine.exceptions.SignedSystemException) SubstateNotFoundException(com.radixdlt.constraintmachine.exceptions.SubstateNotFoundException) NotAResourceException(com.radixdlt.constraintmachine.exceptions.NotAResourceException) VirtualSubstateAlreadyDownException(com.radixdlt.constraintmachine.exceptions.VirtualSubstateAlreadyDownException) ConstraintMachineException(com.radixdlt.constraintmachine.exceptions.ConstraintMachineException) LocalSubstateNotFoundException(com.radixdlt.constraintmachine.exceptions.LocalSubstateNotFoundException) TrailingBytesException(com.radixdlt.engine.parser.exceptions.TrailingBytesException) InvalidPermissionException(com.radixdlt.constraintmachine.exceptions.InvalidPermissionException) TxnParseException(com.radixdlt.engine.parser.exceptions.TxnParseException) DeserializeException(com.radixdlt.serialization.DeserializeException)

Aggregations

ProcedureException (com.radixdlt.constraintmachine.exceptions.ProcedureException)5 SubstateTypeId (com.radixdlt.atom.SubstateTypeId)3 ConstraintScrypt (com.radixdlt.atomos.ConstraintScrypt)3 Loader (com.radixdlt.atomos.Loader)3 DeserializeException (com.radixdlt.serialization.DeserializeException)3 EpochData (com.radixdlt.application.system.state.EpochData)2 RoundData (com.radixdlt.application.system.state.RoundData)2 TokensInAccount (com.radixdlt.application.tokens.state.TokensInAccount)2 REFieldSerialization (com.radixdlt.atom.REFieldSerialization)2 SubstateDefinition (com.radixdlt.atomos.SubstateDefinition)2 com.radixdlt.constraintmachine (com.radixdlt.constraintmachine)2 AuthorizationException (com.radixdlt.constraintmachine.exceptions.AuthorizationException)2 ConstraintMachineException (com.radixdlt.constraintmachine.exceptions.ConstraintMachineException)2 InvalidPermissionException (com.radixdlt.constraintmachine.exceptions.InvalidPermissionException)2 LocalSubstateNotFoundException (com.radixdlt.constraintmachine.exceptions.LocalSubstateNotFoundException)2 MeterException (com.radixdlt.constraintmachine.exceptions.MeterException)2 MissingProcedureException (com.radixdlt.constraintmachine.exceptions.MissingProcedureException)2 UInt256 (com.radixdlt.utils.UInt256)2 Supplier (java.util.function.Supplier)2 Streams (com.google.common.collect.Streams)1