How to upgrade stateV1 to V2 without changing the Contract version? - corda

I have an ObligationV1 and two states ObligationStateV1 and ObligationStateV2.
How do I achieve A state is upgraded while the contract stays the same. where the state goes from V1 to V2 without changing the contract version. Based on the examples exampleLink, docs
It seems that the code will end up looking like this where you have a new ObligationContractV2? The example was trying to achieve
This CorDapp shows how to upgrade a state without upgrading the Contract. But I don't see how does the implementation actually prove that the new states is still referring to the old contract?
open class ObligationContractV2 : UpgradedContractWithLegacyConstraint {
override val legacyContract: ContractClassName = ObligationContractV1.id
override val legacyContractConstraint: AttachmentConstraint = AlwaysAcceptAttachmentConstraint
override fun upgrade(oldState: ObligationStateV1) = ObligationContractV2.ObligationStateV2(oldState.a, oldState.b, 0)
data class ObligationStateV2(val a: AbstractParty, val b: AbstractParty, val value:Int ) : ContractState {
override val participants get() = listOf(a, b)
}
override fun verify(tx: LedgerTransaction) {}
}

The contract class must change whenever you upgrade a state, but the rules it imposes can remain the same.
You could achieve this by delegating the transaction checking to the old contract:
override fun verify(tx: LedgerTransaction) {
ObligationContractV1().verify()
}
You could also delegate the checking to the old contract, and adding additional checks:
override fun verify(tx: LedgerTransaction) {
ObligationContractV1().verify()
additionalChecks()
}
However, note that delegating verify in this way while upgrading states will only work if the original contract isn't hardcoded to verify the transaction in terms of the old state. You'd have to write the original contract in terms of some interface or abstract class implemented by both the old state class and the new state class, or in some other way write the old contract in an open-ended manner. If you didn’t write the old contract in this forward-thinking way initially, you'll have to re-write the verify method.

Related

Ultra low latency processes using Axon Framework

So, I'm working on a PoC for a low latency trading engine using axon and Spring Boot framework. Is it possible to achieve latency as low as 10 - 50ms for a single process flow? The process will include validations, orders, and risk management. I have done some initial tests on a simple app to update the order state and execute it and I'm clocking in 300ms+ in latency. Which got me curious as to how much can I optimize with Axon?
Edit:
The latency issue isn't related to Axon. Managed to get it down to ~5ms per process flow using an InMemoryEventStorageEngine and DisruptorCommandBus.
The flow of messages goes like this. NewOrderCommand(published from client) -> OrderCreated(published from aggregate) -> ExecuteOrder(published from saga) -> OrderExecutionRequested -> ConfirmOrderExecution(published from saga) -> OrderExecuted(published from aggregate)
Edit 2:
Finally switched over to Axon Server but as expected the average latency went up to ~150ms. Axon Server was installed using Docker. How do I optimize the application using AxonServer to achieve sub-millisecond latencies moving forward? Any pointers are appreciated.
Edit 3:
#Steven, based on your suggestions I have managed to bring down the latency to an average of 10ms, this is a good start ! However, is it possible to bring it down even further? As what I am testing now is just a small process out of a series of processes to be done like validations, risk management and position tracking before finally executing the order out. All of which should be done within 5ms or less. Worse case to tolerate is 10ms(These are the updated time budget). Also, do note below in the configs that the new readings are based on an InMemorySagaStore backed by a WeakReferenceCache. Really appreciate the help !
OrderAggregate:
#Aggregate
internal class OrderAggregate {
#AggregateIdentifier(routingKey = "orderId")
private lateinit var clientOrderId: String
private var orderId: String = UUID.randomUUID().toString()
private lateinit var state: OrderState
private lateinit var createdAtSource: LocalTime
private val log by Logger()
constructor() {}
#CommandHandler
constructor(command: NewOrderCommand) {
log.info("received new order command")
val (orderId, created) = command
apply(
OrderCreatedEvent(
clientOrderId = orderId,
created = created
)
)
}
#CommandHandler
fun handle(command: ConfirmOrderExecutionCommand) {
apply(OrderExecutedEvent(orderId = command.orderId, accountId = accountId))
}
#CommandHandler
fun execute(command: ExecuteOrderCommand) {
log.info("execute order event received")
apply(
OrderExecutionRequestedEvent(
clientOrderId = clientOrderId
)
)
}
#EventSourcingHandler
fun on(event: OrderCreatedEvent) {
log.info("order created event received")
clientOrderId = event.clientOrderId
createdAtSource = event.created
setState(Confirmed)
}
#EventSourcingHandler
fun on(event: OrderExecutedEvent) {
val now = LocalTime.now()
log.info(
"elapse to execute: ${
createdAtSource.until(
now,
MILLIS
)
}ms. created at source: $createdAtSource, now: $now"
)
setState(Executed)
}
private fun setState(state: OrderState) {
this.state = state
}
}
OrderManagerSaga:
#Profile("rabbit-executor")
#Saga(sagaStore = "sagaStore")
class OrderManagerSaga {
#Autowired
private lateinit var commandGateway: CommandGateway
#Autowired
private lateinit var executor: RabbitMarketOrderExecutor
private val log by Logger()
#StartSaga
#SagaEventHandler(associationProperty = "clientOrderId")
fun on(event: OrderCreatedEvent) {
log.info("saga received order created event")
commandGateway.send<Any>(ExecuteOrderCommand(orderId = event.clientOrderId, accountId = event.accountId))
}
#SagaEventHandler(associationProperty = "clientOrderId")
fun on(event: OrderExecutionRequestedEvent) {
log.info("saga received order execution requested event")
try {
//execute order
commandGateway.send<Any>(ConfirmOrderExecutionCommand(orderId = event.clientOrderId))
} catch (e: Exception) {
log.error("failed to send order: $e")
commandGateway.send<Any>(
RejectOrderCommand(
orderId = event.clientOrderId
)
)
}
}
}
Beans:
#Bean
fun eventSerializer(mapper: ObjectMapper): JacksonSerializer{
return JacksonSerializer.Builder()
.objectMapper(mapper)
.build()
}
#Bean
fun commandBusCache(): Cache {
return WeakReferenceCache()
}
#Bean
fun sagaCache(): Cache {
return WeakReferenceCache()
}
#Bean
fun associationsCache(): Cache {
return WeakReferenceCache()
}
#Bean
fun sagaStore(sagaCache: Cache, associationsCache: Cache): CachingSagaStore<Any>{
val sagaStore = InMemorySagaStore()
return CachingSagaStore.Builder<Any>()
.delegateSagaStore(sagaStore)
.associationsCache(associationsCache)
.sagaCache(sagaCache)
.build()
}
#Bean
fun commandBus(
commandBusCache: Cache,
orderAggregateFactory: SpringPrototypeAggregateFactory<Order>,
eventStore: EventStore,
txManager: TransactionManager,
axonConfiguration: AxonConfiguration,
snapshotter: SpringAggregateSnapshotter
): DisruptorCommandBus {
val commandBus = DisruptorCommandBus.builder()
.waitStrategy(BusySpinWaitStrategy())
.executor(Executors.newFixedThreadPool(8))
.publisherThreadCount(1)
.invokerThreadCount(1)
.transactionManager(txManager)
.cache(commandBusCache)
.messageMonitor(axonConfiguration.messageMonitor(DisruptorCommandBus::class.java, "commandBus"))
.build()
commandBus.registerHandlerInterceptor(CorrelationDataInterceptor(axonConfiguration.correlationDataProviders()))
return commandBus
}
Application.yml:
axon:
server:
enabled: true
eventhandling:
processors:
name:
mode: tracking
source: eventBus
serializer:
general : jackson
events : jackson
messages : jackson
Original Response
Your setup's description is thorough, but I think there are still some options I can recommend. This touches a bunch of locations within the Framework, so if anything's unclear on the suggestions given their position or goals within Axon, feel free to add a comment so that I can update my response.
Now, let's provide a list of the things I have in mind:
Set up snapshotting for aggregates if loading takes to long. Configurable with the AggregateLoadTimeSnapshotTriggerDefinition.
Introduces a cache for your aggregate. I'd start with trying out the WeakReferenceCache. If this doesn't suffice, it would be worth investigating the EhCache and JCache adapters. Or, construct your own. Here's the section on Aggregate caching, by the way.
Introduces a cache for your saga. I'd start with trying out the WeakReferenceCache. If this doesn't suffice, it would be worth investigating the EhCache and JCache adapters. Or, construct your own. Here's the section on Saga caching, by the way.
Do you really need a Saga in this setup? The process seems simple enough it could run within a regular Event Handling Component. If that's the case, not moving through the Saga flow will likely introduce a speed up too.
Have you tried optimizing the DisruptorCommandBus? Try playing with the WaitStrategy, publisher thread count, invoker thread count and the Executor used.
Try out the PooledStreamingEventProcessor (PSEP, for short) instead of the TrackingEventProcessor (TEP, for short). The former provides more configuration options. The defaults already provide a higher throughput compared to the TEP, by the way. Increasing the "batch size" allows you to ingest bigger amounts of events in one go. You can also change the Executor the PSEP uses for Event retrieval work (done by the coordinator) and Event processing (the worker executor is in charge of this).
There are also some things you can configure on Axon Server that might increase throughput. Try out the event.events-per-segment-prefetch, the event.read-buffer-size or command-thread. There might be other options that work, so it might be worth checking out the entire list of options here.
Although it's hard to deduce whether this will generate an immediate benefit, you could give the Axon Server runnable more memory / CPU. At least 2Gb heap and 4 cores. Playing with these numbers might just help too.
There's likely more to share, but these are the things I have on top of mind. Hope this helps you out somewhat David!
Second Response
To further deduce where we can achieve more performance, I think it would be essential to know what process your application is working on that take the longest. That will allow us to deduce what should be improved if we can improve it.
Have you tried making a thread dump to deduce what part's take up the most time? If you can share that as an update to your question, we can start thinking about the following steps.

Corda - Queries on QueryableState Child Tables

Background
I have a problem with being able to query child data in a sample Corda application, demonstrating how to persisnt hierarchical data using QueryableState.
For reference:
https://github.com/corda/samples-kotlin/tree/master/Features/queryableState-carinsurance
https://www.corda.net/blog/persisting-corda-states-in-custom-database-tables-using-queryablestate/
The car insurance sample demonstrates how to set up:
a One-to-One relationship between PersistentInsurance and PersistentVehicle
a One-to-Many relationship between PersistentInsurance and PersistentClaim
Problem
What the car insurance sample doesn't demonstrate is how to query that data. Building vault queries from PersistentInsurance is fairly trivial as we can use VaultCustomQueryCriteria to build custom query expressions over the properties of PersistentInsurance, however the same is not true for the child tables in the hierarchy. This is because PersistentInsurance extends PersistentState, whereas PersistentVehicle and PersistentClaim don't.
For Reference, the underlying type hierarchy for PersistentState is as follows:
StatePersistable > DirectStatePersistable > PersistentState
interface StatePersistable
interface DirectStatePersistable : StatePersistable {
val stateRef: PersistentStateRef?
}
class PersistentState(#EmbeddedId override var stateRef: PersistentStateRef? = null) : DirectStatePersistable
data class PersistentStateRef(
#Suppress("MagicNumber") // column width
#Column(name = "transaction_id", length = 144, nullable = false)
var txId: String,
#Column(name = "output_index", nullable = false)
var index: Int
) : Serializable {
constructor(stateRef: StateRef) : this(stateRef.txhash.toString(), stateRef.index)
}
Going back to the car insurance sample, we can't use VaultCustomQueryCriteria for PersistentVehicle or PersistentClaim as VaultCustomQueryCriteria::expression has a generic constraint on StatePersistable:
data class VaultCustomQueryCriteria<L : StatePersistable>(
val expression: CriteriaExpression<L, Boolean>,
...
) : CommonQueryCriteria() { ... }
What I've Tried
Implementing StatePersistable on PersistentVehicle and/or PersistentClaim causes the following error when you create a VaultCustomQueryCriteria using any of the properties from those classes:
net.corda.core.node.services.VaultQueryException: Parsing error: Unable to locate Attribute with the the given name [stateRef] on this ManagedType [...$PersistentClaim]
Implementing DirectStatePersistable or PersistentState on PersistentVehicle and/or PersistentClaim causes an internal error when finalizing the transaction. The flow hangs and eventually times out. I wasn't able to determine exactly where the error occurs as the code is buried inside internal implementations for underlying Corda services.
What Does Work (In a Limited Capacity)
I'm aware that we can execute custom SQL queries; for example:
val sqlQuery = buildString {
appendln("SELECT TRANSACTION_ID, OUTPUT_INDEX")
appendln("FROM CLAIM_DETAIL")
appendln("WHERE claimNumber = '123'")
}
val stateRefs = serviceHub.jdbcSession().executeCaseInsensitiveQuery(sqlQuery).map {
val txId = SecureHash.parse(it.getString("TRANSACTION_ID")
val index = it.getInt("OUTPUT_INDEX")
StateRef(txId, index)
}.toList().toBlocking().first()
VaultQueryCriteria(stateRefs = stateRefs)
Needless to say, that's hideous compared to:
VaultCustomQueryCriteria(PersistentClaim::claimNumber.equal("123"))
As for why it works in a limited capacity, this works fine for queries inside the node, which access to the service hub, but doesn't work over RPC as there's no access to a jdbcSession.
So, any ideas (if it's at all possible), on how we can improve the query capability of child tables?
#Matthew Layton I have put your concerns to the engineering team. The team has looked into this.
To address/fix this issue, requires lot of platform changes.
For time being I would suggest you to manage with using native queries. We are planning to prioritise this issue. I will keep you posted on this.

ReceiveStateAndRefFlow does not receive StatesToRecord parameter

In Corda, there is a flow which provides the functionality to send SignedTransaction to another party.
open class SendTransactionFlow(otherSide: FlowSession, stx: SignedTransaction) : DataVendingFlow(otherSide, stx)
And another flow, which sends StatesAndRefs to another party:
open class SendStateAndRefFlow(otherSideSession: FlowSession, stateAndRefs: List<StateAndRef<*>>) : DataVendingFlow(otherSideSession, stateAndRefs)
On the acceptor's side corresponding receiver flow should be invoked:
open class ReceiveTransactionFlow #JvmOverloads constructor(private val otherSideSession: FlowSession,
private val checkSufficientSignatures: Boolean = true,
private val statesToRecord: StatesToRecord = StatesToRecord.NONE) : FlowLogic<SignedTransaction>()
or
class ReceiveStateAndRefFlow<out T : ContractState>(private val otherSideSession: FlowSession) : FlowLogic<#JvmSuppressWildcards List<StateAndRef<T>>>() // which invokes **ReceiveTransactionFlow** with **StatesToRecord.NONE**
The key difference between these two acceptor flows is that ReceiveStateAndRefFlow will resolve SignedTransaction on acceptor's side, but will not record states to the counterparties vault. On the other, hand: ReceiveTransactionFlow accepts StatesToRecord property and will store states into the counterparty's vault.
Question: What is the rationale that ReceiveStateAndRefFlow doesn't accept StatesToRecord property?
Turns out there is no particular reason why StatesToRecord cannot be set but there are some tricky edge cases to deal with which may end up in CorDapp developers messing up their vault!
For example: when you force the storing of a single state in the vault the corresponding output in the same transaction will not be stored, resulting you having an unconsumed state in the vault which is actually consumed.
Normally, this wouldn't matter too much because you can't spend it anyway. However, it will result in confusing vault query behaviour.

Understanding the relationship between Liskov and OCP

I am solidifying my understanding of the relationship between Liskov Substitutional Principal and Open Close Principal. If anybody could confirm my deductions and answer my questions below that would be great.
I have the following classes. As you can see, B is derived from A and it is overriding the DisplayMessage function in order to alter the behavior.
public class A
{
private readonly string _message;
public A(string message)
{
_message = message;
}
public virtual void DisplayMessage()
{
Console.WriteLine(_message);
}
}
public class B : A
{
public B(string message) : base(message){}
public override void DisplayMessage()
{
Console.WriteLine("I'm overwriting the expected behavior of A::DisplayMessage() and violating LSP >:-D");
}
}
Now in my bootstrap program, ShowClassTypeis expecting an object of Type A which should helpfully write out what class Type it is. However B is violating LSP so when it's DisplayMessage function is called it prints a completely unexpected message and essentially interferes with the intended purpose of ShowClassType.
class Program
{
static void Main(string[] args)
{
A a = new A("I am A");
B b = new B("I am B");
DoStuff(b);
Console.ReadLine();
}
private static void ShowClassType(A model)
{
Console.WriteLine("What Class are you??");
model.DisplayMessage();
}
}
So my question is, am I right to conclude that ShowClassType is now violating the Open Close Principal because now that Type B can come in and change the expected function of that method, it is no longer closed for modification (ie. to ensure it maintains it's expected behaviour you would have to alter it so that it first checks to make sure we are only working with an original A object)?
Or, inversely is this just a good example to show that ShowClassType is closed for modification and that by passing in a derived type (albeit a LSP violating one) we have extended what it is meant to do?
Lastly, is it bad practice to create virtual functions on Base classes if the base class is not abstract? By doing so, are we not just inviting derived classes to violate the Liskov Substitution principal?
Cheers
I'd say it's not ShowClassType that is violating the Open/Closed Principle.
It's only class B that is violating the Liskov Substitution Principle. A is Open for extension, but closed for modification.
From Wikipedia,
an entity can allow its behaviour to be modified without altering its source code.
It's obvious that the source code of A is not modified. Nor are private members of A being used (which would also be a violation of the Open/Closed principle in my book). B strictly uses the public interface of A, so although the Open/Closed principle is obeyed the Liskov Substitution Principle is violated.
The last question is worth a discussion in and of itself. A related question on SO is here.
I think it is not violate not LSP and not OCP in THIS context of using.
For my opinion, ShowClassType not violation OCP:
1. Function can not break OCP, only class architecture can do this.
2. You can add new behaviours to derived classes from A - so it do not break OCP
What about LSP? Your reason - user not expected get this message? But he got some message! If function overriding returns some message i think is ok in THIS context of your code.
If function, that add two numbers is overrides, and 1+1 returns 678 it not expectable for me and is bad. BUT, if for scientist of Physics from Mars planet it can be good answer.
DO NOT ANALYSE PROBLEM WITHOUT ALL CONTEXT!!! You must get whole picture of problem. And, of course

Is interception worth the overhead it creates?

I'm in the middle of a significant effort to introduce NHibernate into our code base. I figured I would have to use some kind of a DI container, so I can inject dependencies into the entities I load from the database. I chose Unity as that container.
I'm considering using Unity's interception mechanism to add a transaction aspect to my code, so I can do e.g. the following:
class SomeService
{
[Transaction]
public void DoSomething(CustomerId id)
{
Customer c = CustomerRepository.LoadCustomer(id);
c.DoSomething();
}
}
and the [Transaction] handler will take care of creating a session and a transaction, committing the transaction (or rolling back on exception), etc.
I'm concerned that using this kind of interception will bind me to using Unity pretty much everywhere in the code. If I introduce aspects in this manner, then I must never, ever call new SomeService(), or I will get a service that doesn't have transactions. While this is acceptable in production code, it seems too much overhead in tests. For example, I would have to convert this:
void TestMethod()
{
MockDependency dependency = new MockDependency();
dependency.SetupForTest();
var service = SomeService(dependency);
service.DoSomething();
}
into this:
void TestMethod()
{
unityContainer.RegisterType<MockDependency>();
unityContainer.RegisterType<IDependency, MockDependency>();
MockDependency dependency = unityContainer.Resolve<MockDependency>();
dependency.SetupForTest();
var service = unityContainer.Resolve<SomeService>();
service.DoSomething();
}
This adds 2 lines for each mock object that I'm using, which leads to quite a bit of code (our tests use a lot of stateful mocks, so it is not uncommon for a test class to have 5-8 mock objects, and sometimes more.)
I don't think standalone injection would help here: I have to set up injection for every class that I use in the tests, because it's possible for aspects to be added to a class after the test is written.
Now, if I drop the use of interception I'll end up with:
class SomeService
{
public void DoSomething(CustomerId id)
{
Transaction.Run(
() => {
Customer c = CustomerRepository.LoadCustomer(id);
c.DoSomething();
});
}
}
which is admittedly not as nice, but doesn't seem that bad either.
I can even set up my own poor man's interception:
class SomeService
{
[Transaction]
public void DoSomething(CustomerId id)
{
Interceptor.Intercept(
MethodInfo.GetCurrentMethod(),
() => {
Customer c = CustomerRepository.LoadCustomer(id);
c.DoSomething();
});
}
}
and then my interceptor can process the attributes for the class, but I can still instantiate the class using new and not worry about losing functionality.
Is there a better way of using Unity interception, that doesn't force me to always use it for instantiating my objects?
If you want to use AOP but are concerned abut Unity then I would recommend you check out PostSharp. That implements AOP as a post-compile check but has no changes on how you use the code at runtime.
http://www.sharpcrafters.com/
They have a free community edition that has a good feature set, as well as professional and enterprise versions that have significantly enhanced feature sets.

Resources