use of com.radixdlt.engine.RadixEngineException in project radixdlt by radixdlt.
the class RadixEngineMempool method add.
@Override
public REProcessedTxn add(Txn txn) throws MempoolRejectedException {
if (this.data.size() >= maxSize) {
throw new MempoolFullException(this.data.size(), maxSize);
}
if (this.data.containsKey(txn.getId())) {
throw new MempoolDuplicateException(String.format("Mempool already has command %s", txn.getId()));
}
final RadixEngineResult<LedgerAndBFTProof> result;
try {
RadixEngine.RadixEngineBranch<LedgerAndBFTProof> checker = radixEngine.transientBranch();
result = checker.execute(List.of(txn));
} catch (RadixEngineException e) {
// TODO: allow missing dependency atoms to live for a certain amount of time
throw new MempoolRejectedException(e);
} finally {
radixEngine.deleteBranches();
}
var mempoolTxn = MempoolMetadata.create(System.currentTimeMillis());
var data = Pair.of(result.getProcessedTxn(), mempoolTxn);
this.data.put(txn.getId(), data);
result.getProcessedTxn().substateDependencies().forEach(substateId -> substateIndex.merge(substateId, Set.of(txn.getId()), Sets::union));
return result.getProcessedTxn();
}
use of com.radixdlt.engine.RadixEngineException in project radixdlt by radixdlt.
the class RadixEngineStateComputerTest method setupGenesis.
private void setupGenesis() throws RadixEngineException {
var branch = radixEngine.transientBranch();
var result = branch.execute(genesisTxns.getTxns(), PermissionLevel.SYSTEM);
var genesisValidatorSet = result.getProcessedTxns().get(0).getEvents().stream().filter(REEvent.NextValidatorSetEvent.class::isInstance).map(REEvent.NextValidatorSetEvent.class::cast).findFirst().map(e -> BFTValidatorSet.from(e.nextValidators().stream().map(v -> BFTValidator.from(BFTNode.create(v.validatorKey()), v.amount())))).orElseThrow(() -> new IllegalStateException("No validator set in genesis."));
radixEngine.deleteBranches();
var genesisLedgerHeader = LedgerProof.genesis(new AccumulatorState(0, hasher.hash(genesisTxns.getTxns().get(0).getId())), genesisValidatorSet, 0);
if (!genesisLedgerHeader.isEndOfEpoch()) {
throw new IllegalStateException("Genesis must be end of epoch");
}
radixEngine.execute(genesisTxns.getTxns(), LedgerAndBFTProof.create(genesisLedgerHeader), PermissionLevel.SYSTEM);
}
use of com.radixdlt.engine.RadixEngineException in project radixdlt by radixdlt.
the class RadixEngineStateComputerTest method preparing_system_update_from_vertex_should_fail.
@Test
public void preparing_system_update_from_vertex_should_fail() throws TxBuilderException {
// Arrange
var txn = radixEngine.construct(new NextRound(1, false, 0, i -> proposerElection.getProposer(View.of(i)).getKey())).buildWithoutSignature();
var illegalTxn = TxLowLevelBuilder.newBuilder(currentForkView.currentForkConfig().engineRules().serialization()).down(SubstateId.ofSubstate(txn.getId(), 1)).up(new RoundData(2, 0)).end().build();
var v = UnverifiedVertex.create(mock(QuorumCertificate.class), View.of(1), List.of(illegalTxn), proposerElection.getProposer(View.of(1)));
var vertex = new VerifiedVertex(v, mock(HashCode.class));
// Act
var result = sut.prepare(ImmutableList.of(), vertex, 0);
// Assert
assertThat(result.getSuccessfulCommands()).hasSize(1);
assertThat(result.getFailedCommands()).hasValueSatisfying(new Condition<>(e -> {
var ex = (RadixEngineException) e;
var cmException = (ConstraintMachineException) ex.getCause();
return cmException.getCause() instanceof InvalidPermissionException;
}, "Is invalid_execution_permission error"));
}
use of com.radixdlt.engine.RadixEngineException in project radixdlt by radixdlt.
the class InMemoryEngineStore method transaction.
@Override
public <R> R transaction(TransactionEngineStoreConsumer<M, R> consumer) throws RadixEngineException {
return consumer.start(new EngineStoreInTransaction<>() {
@Override
public void storeTxn(REProcessedTxn txn) {
synchronized (lock) {
txn.stateUpdates().forEach(update -> {
store.storedState.put(update.getId(), update);
// FIXME: Superhack
if (update.isBootUp()) {
if (update.getParsed() instanceof TokenResource) {
var tokenDef = (TokenResource) update.getParsed();
store.resources.put(tokenDef.addr(), update::getStateBuf);
} else if (update.getParsed() instanceof VirtualParent) {
var p = (VirtualParent) update.getParsed();
var typeByte = p.data()[0];
var mapKey = SystemMapKey.ofSystem(typeByte);
store.maps.put(mapKey, update.getRawSubstateBytes());
} else if (update.getParsed() instanceof ValidatorData) {
var data = (ValidatorData) update.getParsed();
var mapKey = SystemMapKey.ofSystem(update.typeByte(), data.validatorKey().getCompressedBytes());
store.maps.put(mapKey, update.getRawSubstateBytes());
} else if (update.getParsed() instanceof SystemData) {
var mapKey = SystemMapKey.ofSystem(update.typeByte());
store.maps.put(mapKey, update.getRawSubstateBytes());
}
} else if (update.isShutDown()) {
if (update.getParsed() instanceof ValidatorData) {
var data = (ValidatorData) update.getParsed();
var mapKey = SystemMapKey.ofSystem(update.typeByte(), data.validatorKey().getCompressedBytes());
store.maps.remove(mapKey);
} else if (update.getParsed() instanceof SystemData) {
var mapKey = SystemMapKey.ofSystem(update.typeByte());
store.maps.remove(mapKey);
}
}
});
}
}
@Override
public void storeMetadata(M metadata) {
store.metadata = metadata;
}
@Override
public ByteBuffer verifyVirtualSubstate(SubstateId substateId) throws VirtualSubstateAlreadyDownException, VirtualParentStateDoesNotExist {
synchronized (lock) {
var parent = substateId.getVirtualParent().orElseThrow();
var update = store.storedState.get(parent);
if (update == null || !(update.getParsed() instanceof VirtualParent)) {
throw new VirtualParentStateDoesNotExist(parent);
}
var inst = store.storedState.get(substateId);
if (inst != null && inst.isShutDown()) {
throw new VirtualSubstateAlreadyDownException(substateId);
}
return update.getStateBuf();
}
}
@Override
public Optional<ByteBuffer> loadSubstate(SubstateId substateId) {
synchronized (lock) {
var inst = store.storedState.get(substateId);
if (inst == null || !inst.isBootUp()) {
return Optional.empty();
}
return Optional.of(inst.getStateBuf());
}
}
@Override
public CloseableCursor<RawSubstateBytes> openIndexedCursor(SubstateIndex<?> index) {
return InMemoryEngineStore.this.openIndexedCursor(index);
}
@Override
public Optional<ByteBuffer> loadResource(REAddr addr) {
synchronized (lock) {
var supplier = store.resources.get(addr);
return supplier == null ? Optional.empty() : Optional.of(supplier.get());
}
}
});
}
use of com.radixdlt.engine.RadixEngineException in project radixdlt by radixdlt.
the class VoteHandler method handleRequest.
@Override
public UpdateVoteResponse handleRequest(UpdateVoteRequest request) throws CoreApiException {
coreModelMapper.verifyNetwork(request.getNetworkIdentifier());
final Txn signedTx;
try {
signedTx = radixEngine.constructWithFees(this::buildVote, false, REAddr.ofPubKeyAccount(validatorKey), NotEnoughNativeTokensForFeesException::new).signAndBuild(hashSigner::sign);
} catch (TxBuilderException e) {
throw CoreApiException.badRequest(coreModelMapper.builderErrorDetails(e));
}
try {
radixEngineStateComputer.addToMempool(signedTx);
return new UpdateVoteResponse().transactionIdentifier(coreModelMapper.transactionIdentifier(signedTx.getId())).duplicate(false);
} catch (MempoolDuplicateException e) {
return new UpdateVoteResponse().transactionIdentifier(coreModelMapper.transactionIdentifier(signedTx.getId())).duplicate(true);
} catch (MempoolFullException e) {
throw coreModelMapper.mempoolFullException(e);
} catch (MempoolRejectedException e) {
throw coreModelMapper.radixEngineException((RadixEngineException) e.getCause());
}
}
Aggregations