use of com.radixdlt.constraintmachine.exceptions.AuthorizationException 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));
}
use of com.radixdlt.constraintmachine.exceptions.AuthorizationException in project radixdlt by radixdlt.
the class RadixEngine method getSignedByKey.
private Optional<ECPublicKey> getSignedByKey(ParsedTxn parsedTxn, ExecutionContext context) throws AuthorizationException {
if (!context.skipAuthorization() && context.permissionLevel() != PermissionLevel.SYSTEM) {
var payloadHashAndSigMaybe = parsedTxn.getPayloadHashAndSig();
if (payloadHashAndSigMaybe.isPresent()) {
var payloadHashAndSig = payloadHashAndSigMaybe.get();
var hash = payloadHashAndSig.getFirst();
var sig = payloadHashAndSig.getSecond();
var pubKey = ECPublicKey.recoverFrom(hash, sig).orElseThrow(() -> new AuthorizationException("Invalid signature"));
// TODO: do we still need this verify?
if (!pubKey.verify(hash, sig)) {
throw new AuthorizationException("Invalid signature");
}
return Optional.of(pubKey);
}
}
return Optional.empty();
}
use of com.radixdlt.constraintmachine.exceptions.AuthorizationException 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;
}
}
use of com.radixdlt.constraintmachine.exceptions.AuthorizationException 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();
}
use of com.radixdlt.constraintmachine.exceptions.AuthorizationException in project radixdlt by radixdlt.
the class ValidatorRegisterConstraintScrypt method main.
@Override
public void main(Loader os) {
os.substate(new SubstateDefinition<>(ValidatorRegisteredCopy.class, SubstateTypeId.VALIDATOR_REGISTERED_FLAG_COPY.id(), buf -> {
REFieldSerialization.deserializeReservedByte(buf);
var epochUpdate = REFieldSerialization.deserializeOptionalNonNegativeLong(buf);
var key = REFieldSerialization.deserializeKey(buf);
var flag = REFieldSerialization.deserializeBoolean(buf);
return new ValidatorRegisteredCopy(epochUpdate, key, flag);
}, (s, buf) -> {
REFieldSerialization.serializeReservedByte(buf);
REFieldSerialization.serializeOptionalLong(buf, s.epochUpdate());
REFieldSerialization.serializeKey(buf, s.validatorKey());
buf.put((byte) (s.isRegistered() ? 1 : 0));
}, buf -> REFieldSerialization.deserializeKey(buf), (k, buf) -> REFieldSerialization.serializeKey(buf, (ECPublicKey) k), k -> new ValidatorRegisteredCopy(OptionalLong.empty(), (ECPublicKey) k, false)));
os.procedure(new DownProcedure<>(VoidReducerState.class, ValidatorRegisteredCopy.class, d -> new Authorization(PermissionLevel.USER, (r, c) -> {
if (!c.key().map(d.validatorKey()::equals).orElse(false)) {
throw new AuthorizationException("Key does not match.");
}
}), (d, s, r, c) -> {
return ReducerResult.incomplete(new UpdatingRegisteredNeedToReadEpoch(d.validatorKey()));
}));
os.procedure(new ReadProcedure<>(UpdatingRegisteredNeedToReadEpoch.class, EpochData.class, u -> new Authorization(PermissionLevel.USER, (r, c) -> {
}), (s, u, r) -> ReducerResult.incomplete(s.readEpoch(u))));
os.procedure(new UpProcedure<>(UpdatingRegistered.class, ValidatorRegisteredCopy.class, u -> new Authorization(PermissionLevel.USER, (r, c) -> {
}), (s, u, c, r) -> {
s.update(u);
return ReducerResult.complete();
}));
}
Aggregations