 Good day, everyone. I hope you are enjoying the Hyperledger Global Forum event so far. My name is Arnab Chatterjee, and I'm going to present compatibility and pitfalls of architectural patterns with blockchain use cases. So there's a poll for your information in the beside the chat window. Please feel free to share your responses over there. So let me introduce myself. I am a technical lead currently associated with R3 and I was previously associated with organizations like Bosch and NEC Corporation, where I gathered experience for the last eight years in building enterprise applications out of that the last five years in designing and architecting blockchain applications. I am the co-author of multiple research papers on architecting blockchain systems in production. And I also represent India on behalf of the National Body of Standards, the Bureau of Indian Standards at ISO T3307, the Global Blockchain and DLT Standards. I'm a committee member there and I contribute towards identity and privacy standards. Of late, I have been also contributing to the Hyperledger Tooling Project, which is a new addition. And this project aims to help the newcomers start their open source contribution towards Hyperledger projects. So you can visit this URL and check it out. So this is the outline of what I will be presenting today for the next 20 to 25 minutes. I will start with the rationale of this talk, followed by a head first deep dive into some architectural patterns. We will end this talk with an approach to architecting blockchain use cases using the evolutionary style of architecture. So before we begin, let me focus, let me emphasize that we will be focusing our discussion mostly on these blockchain platforms, that is Hyperledger Fabric and Enterprise Ethereum and Enterprise Ethereum encompassing the Hyperledger Basu and Corum kind of projects. So throughout the presentation, I will be using ETH or Ethereum for brevity. And please feel free to ask any questions and put the questions in the Q&A box. I'll try to answer them towards the end of the presentation. So let's get started. So why this presentation? So blockchain platforms has been in constant flux. Bug features, bug fixes features are these are constantly making their way into new blockchain platform releases. And our experience in building production-grade enterprise blockchain applications is pretty vast. But when we compare it with building blockchain production-grade applications, it has been quite limited. I mean, like comparing it to the former. So the developer fraternity is still figuring things out, like how they are going to go about things. And these things, as I'm calling it, they manifest themselves as technical constraints. So there are a lot of these technical constraints that make our way into it, into our design. And you have to be aware of that. So what is our way out? Like how can we navigate our way through with the constant flux of blockchain platforms evolving? And we have to design our applications. So first as I see it is awareness of these architectural patterns or patterns as I call it. Knowing the constraints more in detail and specifically what architectural patterns work and what architectural patterns don't work with blockchain platforms. So this will be basically the first part of the presentation. The second part of the presentation is how to be agile and build architectures in a such a way that they evolve over time to reveal the best of us. And we do not get ensnared by these pitfalls. So we can basically protect our application by adopting the evolutionary style of building architectures with blockchain. So let's get started with some of the patterns. So the first pattern that we are going to look at is the good old layered monolith architecture. So in its very basic form it has these three layers. It has the presentation business and the persistence layer. And the persistence layer is basically talking to your blockchain through these SDKs or libraries as we call it. And it is worth noting that this communication pattern between this persistence and the blockchain layer is typically synchronous in nature. That means it waits until the processing is not complete. So it is easy on time and budget and it's a great fit for proof of concept implementations. And it's good for people looking out to test out blockchain. However, it is not scalable immediately and it's almost throw away most of the times if we do not design our business logic properly. If you do not decouple the business logic properly. So you need to develop some sort of abstractions on the business logic so that you want to use the business logic later. So this is the first pattern. The second is the event-driven architecture or EDA for short. Here, unlike the synchronous messaging pattern, here the user gets an immediate response. So the user is getting acknowledgement and then the user is that the request is basically logged into a queue or a message broker. And which is then a synchronously processed at the backend. And finally, once the processing is complete, the user is notified of the completion of the request through some sort of notification process. Or through an email so it can be either ways. So EDA basically comprises of an initiating event that we just saw, which gets registered in a message broker. One or more consumers or message processors processes these events. And finally, the processing event, the response event is sent back to the user. So if we just relate this to the blockchain kind of architecture, the user request is basically the initiating event. And the contract event is the processing event, which is the response event. So blockchains indeed follow the EDA style of asynchronous communication. And that's why EDAs also exhibit very high degree of responsiveness due to its asynchronous nature. Another thing that EDA addresses is basically the on-chain off-chain consistency concern that how can we ensure that the off-chain is always consistent with the on-chain state. So we can ensure that the state of the off-chain is only updated as per the sequence of the contract events that we are emitting. So contract events in some way represent the right ahead log that we had for databases. Now talking about concurrency, there's a very high degree of concurrency as well in EDA kind of an architecture. So ledger image specific events like my transaction is sent, my transaction is mined, the contract event is emitted. So with these granular events, it's very easy to model concurrent applications, which also in turn becomes very performant in nature. And finally the events also acts as natural extensibility points. Additional logic can be hooked up to the events in the future that enable high degree of extensibility to the system. Moving on to the pitfalls for EDA, the first is basically to decide the purpose of the contract events. So this is very important, which I'm going to discuss in the subsequent slides. But the purpose can be either of the two. Either it is acting as a state change career or it is acting as a state change notification career. So we'll move on temporarily. So to capture these events, EDA kind of requires some sort of event streaming logic. That means you need something like a rabid MQ or a Kafka to stream these events back to any good old service. Not every service is completely equipped with all these information about contract events and whom to watch out for and all of that stuff. Another concern is that how you debug and monitor your application. And if anything goes wrong, how do you come out of that like the recovery part of it? So those are some of the things of concern in typically in the EDA style of architecture. Now moving on to a very interesting pattern, which is not an architectural pattern that is the event sourcing pattern, which is a storage pattern. So event sourcing pattern advocates the storage of storing the intermediate history of events like facts, along with the current state of the system. So this way one can go back to the past state by replaying the events. So this sounds familiar because blockchain is a natural implementation of this. So transaction act as state change careers to the blockchain. And once the transactions are executed on the smart contract, the smart contract emit this contract events, which then act as state change careers for updating the off-chain storage. So this creates a natural event sourcing kind of a pattern. So in this diagram, every actor is holding a database on their own, which they use for treating. And they send transactions to the ledger and the ledger image event after processing the transaction. And each actor is notified events and they update their database accordingly without making any additional calls to the ledger. So this enables off-chain segregation and off-chain state representation. And this basically creates something like a CQRS or command query responsibility segregation as we call it. So why should we be concerned about the purpose of the event that I was mentioning? So in the first case, we can see that the usage is basically of maintaining a simple user balance. So you have an address and you have a balance of the user on the ledger. So the complete information about the state change that is the balance update through the deposit or withdraw kind of events is handled by the events themselves. So you do not need to go to the ledger to explicitly query. So these are basically your fat events as we call it. The second use case is basically of registering users on the system. Naturally, there might be more data about the users on the ledger and piggybacking all of these data as parameters on the contract event data is not basically practical. So it's practical, however, to use these events as notifications to services off-chain. But in this case, the slim events basically act as state change notifiers. Using the fat events, it is actually easy to construct the off-chain state because you don't need to go to the ledger again to query. But I must also say that it is also possible to update the off-chain state just by looking at these slim events. But there are certain caveats to it. You have to be very careful that no other party is actually updating the state of the ledger while you are going to make an explicit call. And even if it is updated, some ledgers like Fabric allows us to read the history state. But we have to be careful that not all ledgers allow you to do this. Specifically for each type of ledger, it's not possible here. So this basically doubles up. The ledger is basically doubling up as your state change event store. You are storing all the state changes through these events, through these contract events. And it's there for all the actors, coupled along with their respective databases, which allows them to read data conveniently from the off-chain storage. They do not have to go to the on-chain storage. This pattern is very powerful because it allows seamless querying for each of these actors on their respective databases. And they can use that existing known languages like SQL or any no-SQL kind of languages to query data. And they do not have to go through multiple data sources like the ledger, the private data collection, which basically adds to your performance lag when you're querying the system. So this is also a powerful pattern. Some things to watch out for here is that a lot of people, including me at some point in time in the past, we confused event sourcing with the event-driven architecture. So event sourcing is basically a storage pattern. But event-driven architecture is an architectural pattern, right? Defining the structure of the system and its components. And finally, we have to be aware that these history-quaring capabilities that I was mentioning about, it's not there for all ledgers. It's only there for certain ledgers like fabric. Okay. The next is one of my favorites, which is basically the microkernel architecture. The motivation of using microkernel architecture comes from the immutable and sensitive nature of smart contracts. That one smart contract that deployed is challenging to make changes. And also the fact that contracts are very expensive to build and require too much of hard work to audit and get things in place before they're finally deployed on the ledger. So we can apply microkernel architecture to the core contract here. The core contract is basically the contract with the vanilla functionality that we can say with some degree of confidence will not change over time, right? And the part that changes are modeled as plugins over here. And these plugins actually extend the functionality of the vanilla contract. And then we register or deregister these contracts dynamically at runtime through the smart contract registry. And the vanilla contract can basically call these plugin contracts through a proxy here. A nice example of this is like how fabric system chain codes are designed that enable pluggable transaction endorsement and validation, right? You can, you know, plug in the custom BCC or QCC kind of chain codes. Some of the areas to watch out for in general is that how these vanilla contracts are designed and deployed. The AP design of these vanilla contracts are quite challenging and can be difficult to get right at first. And also, you know, we have to be aware of these special ledger considerations, like how fabric allows cross chain code calls. Like one can only do cross chain code calls in the same channel. And then you can, you know, you can write using doing cross chain code channels in the same channel. But when it goes to different channels, you can just read when you do cross chain code calls. So this is another thing to watch out for. Next up is service based architecture or SBA or SOA as we also know, call it a service oriented architecture. So service oriented architecture divides the entire application into services based on the domain, right? And service oriented architectures typically have around, you know, 7 to 12 services that share a common persistence mechanism, like a database or blockchain in this case, right? Based on this scalability and the performance needs of service oriented architecture, we can basically scale up of these services, you know, for better performance, load balancing and fault tolerance, right? So when we use service oriented architecture in blockchain, then in an architecture like this, specifically concurrency issues are. So for example, fabric, which does not allow modifying the same key in the read write set in two or more transactions in the same block, right? Then you need to coordinate, right? It's basically called the MVCC, multi version concurrency control check. And again, in Ethereum, you have these problems of nonce, right? So Ethereum on the other hand requires these transactions from an account to be sequenced using a nonce or a number used only once. And these services being kind of independent processes, they fail to cater to this concurrency needs without complex coordination. And this is where the central transaction orchestrator comes in, right? With persistent memory or a database. So the orchestrator serves multiple purposes. So it first it caters to these special concurrency needs as I was telling about, right? Like avoiding the MVCC conflicts or the nonce requirements. It also removes the need for each service to know about, you know, blockchain network specifics, like, you know, the node information, which peer should I send a transaction, the signing mechanism, the contract information and all of that stuff. On the other hand, the orchestrator also does some good job in, you know, planning the concurrency of the system, like it can group and segregate transactions, you know, that are independent of each other. And then they can, you know, plan this transaction executions in a very nice way. So you can get nice, nice guarantees over here. So one of the worthy mentions over here is that there's a there's a project called Firefly that was supposed to be submitted to the Hyperledge Labs project, which, which does something similar to this. Okay, I've seen this biggie for the last micro services, micro services are typically one of the most hyped architectural patterns, right? And it is a very close relative of the service oriented architecture. But one of the biggest differences of micro services from service oriented architecture is basically the number of services that are there, right? In SOAs, we have around 7 to 12. But in micro services, it's in order of, you know, hundreds, or maybe more, right, which are completely independent of each other. I want to, you know, emphasize this fine because micro services should not typically talk to each other because then they don't make sense in scaling, right? Then basically your, your, your performance and all of these benefits get, get subsumed by, you know, the overhead of the communication. Now, if we take this discussion, right, and we contextualize it to our previous discussion on SOA, right? We can recall that the central ledger needs something like an orchestrator, right, to care to take care of these MVCC or the nonc issues at the very bare minimum. Now, the moment we add the central orchestrator over here, the whole point of micro service fails, right? Because every service is now going to talk to the central orchestrator. So in my opinion, right, using micro services with blockchain is mostly an anti pattern, I would say. Unless your micro service is completely independent and can connect to the ledger independently and have all these logic inside their respective services. Otherwise, I will not kind of much advocate with going with micro service architecture. Okay, we saw a lot of architectural patterns. Now, what next? So the next thing is that we have understood a lot about these architectural patterns and we have seen that, you know, what are the pitfalls? What are the advantages? What are the compatibility kind of things that we can have by looking at these patterns? And it's an evolutionary thing, right? So as I was saying, blockchain platforms evolve and we have to continuously experiment with different architectural styles and, you know, ensure that we are not doing harm to our system at the same time, right? We cannot continuously do too many changes up to our system just to figure out what fits and what does not. So how does a newcomer or anyone who is willing to start off with a project, how do they go about it, right? So at least in my experience and in my organizational experience, what I have realized is that, you know, building these evolutionary architectures help, right? So the first thing that we have to figure out is that, you know, while starting a project, what are the software quality metrics or quality attributes as we call it, right? That are fundamental to building any system, right? So our objective would be to typically, you know, take around three or five metrics for our project. And then we have to decide on these quality attributes and do a lot of brainstorming with all the stakeholders and kind of finalize these top three. Now, once we have these attributes, right, we can then plug them in into a system-wide architectural fitness function, right? So this F, big F is a function of like A1, A2, up till A and where, you know, each of AI is basically your quality attribute, right? So for example, let's say that we chose performance, availability, security and modularity, right? We can then key in each of these attributes into F, right? Where these AI are basically your performance, availability, security and modularity. And once we have this entire, you know, function, we can make guidance experiments, right? And then learn about the trade-offs that we have to make while we design the architecture. So the process goes something like this, right? So we implement a baseline architecture. That is, let's say we start with a layered monolith. And then we, you know, evaluate this F for our system, right? Let's say it's some number. At the very minimum, you can have, you know, a summation of all these attributes, right? So once we have it, right, then you discover that what all... So once you implement it, then you measure, right? What's the overall value of F? And once you have measured, then the next stage is to, you know, discover what are the improvements. So with our experience in these patterns and all, we will make these improvements to the architecture. We will make these changes to the architecture and build an incremental architecture. That is the next version of the system, right? And this incremental version is basically what we will call with a new version release. And once we have done it, we will circle back to measuring that F value again, right? Over here, number two, right? And if we find that the measurement that we have got after doing this incremental change is better than the previous one, then we can proceed with that direction. That means that it will give us, you know, some sort of hint that we are going in the right direction. Because what happens typically is that once you make any changes to any architecture, you're essentially doing a trade-off. And the moment you do a trade-off, you cannot exactly quantify the positive or the negative impact you had on the system. So to quantify it at the overall level, that's where this system-wide architectural fitness function comes in. So this is a very interesting concept that at least I learned, you know, in my tenure. And I'm still learning over here. And if you want to know more basically about how these evolutionary architectures work, I recommend reading, I recommend you to read this book by Neil Ford and Rebecca Parsons on building evolutionary architectures. That's a pretty interesting read. So that's all from my side. Thank you for attending the presentation and listening patiently. I am open for questions, so let's look at the Q&A tab for any questions. Okay, so there are no questions. But since I've got a little bit of time, let me show you something about the quality attributes. So when we start with the project, I've taken this from a very interesting resource called Developer to Architect. We typically pick some of these candidate architectural characteristics. And once we pick them up, we derive these top characteristics, this top three or five driving characteristics for our system. And then once you have got this, you can then find out the pros and cons of each of these architectural patterns by looking at a metric something like this. Of course, this is not contextualized to blockchain. But of course, when you look at these patterns in general, it gives you a fair amount of idea that what patterns have what characteristics that they exhibit. And then you can go back to some of these lessons that we learned today, some of these things that we discussed today. And you can then kind of incrementally build your system starting small and then moving on to advanced techniques as we move on. Okay, so any questions? Okay, I got a question from Shonok. The previous slide, it's same for any architecture, how it is different for blockchain. Yes, that's an excellent question. So this slide is same for all the architectural patterns. However, at the beginning of the presentation, as I was saying that some architectural patterns have certain compatibility with blockchain and some architectural patterns have some pitfalls. So it's not enough in my opinion to just know what works and what doesn't. We also have to know these compatibility points or pitfalls before we proceed with some of these architectures. So for example, as I was telling about microservice architecture, a lot of the people in my organization ask that, why don't you do microservice architecture? As an architect, when we start with the project, we are not aware of these pitfalls. We are not aware that we need the central kind of an orchestrator to send all those transactions through that will coordinate all those transactions, have all those concurrency issues fixed, taken care of, and then build it. So this previous knowledge about these compatibility pitfalls helps a lot. So that's why you need to couple this slide, this metrics, along with the knowledge of these constraints and pitfalls and the compatibility as well. I hope that answers the question. Okay, there's one more question. Can you talk a bit about compatibility between different architecture patterns? Does it make sense to utilize multiple at the same time? Yes, absolutely. Yes, that makes perfect sense. And that's an excellent question. So often what we do is that, so for example, when we design smart contracts, one of the things that we know how to look in smart contracts is how microkernel architectures help there. No matter what kind of architecture you have for your off-chain or for your dApp, it always makes sense to have your smart contracts modular and reusable. So you don't have to decouple those smart contracts later and deploy newer versions of them. So upfront, if you have the knowledge that I'm going to use always microkernel kind of an architecture for smart contracts or then use the central event orchestrator for having all the transactions go through it and manage the concurrency aspects to it. So there you have it like I have just coupled service-oriented architecture and microkernel architecture. So yeah, you can obviously compile these patterns. Are there architectural pitfalls when designing with multiple blockchains, hyperledger, EBSI, Ethereum or Cardano? That's another excellent question. So yes, so in my opinion, you have to be very much aware of these pitfalls or compatibilities of the pattern with the ledger platform. So certain platforms require you to design your architecture in a certain way. So if you have that knowledge, it will help you to design your components, your modules with ease, I would say. So basically when you combine these, probably if you have, I don't know if that's a question, if you have a system where you have multiple ledger platforms or you have to support multiple ledger platforms, then of course you have to make some of these tradeoffs and some of these decisions that take into account these specific nuances and these constraints of the platforms. Okay, there's one more question. What are the risks of event-driven systems? I'm often somewhat uncomfortable in case an event disappears. Oh, that's another excellent question. So yes, I have faced this as well. So what I would suggest is that events typically in blockchain are kind of ephemeral in nature. Unless you persisted in some sort of an event store like a Kafka or a Rabbit MQ or maybe some managed cloud offering like Azure Service Bus, it becomes difficult to deal with those events. And typically when you have multiple consumers consuming those events. I would recommend that you use some sort of event broker to hold your events persistently on disk and use the relevant patterns. Like you can have one producer, multiple consumer kind of a pattern or you can. And one of the other reliability things is you're just mentioning is that how do you ensure that the event doesn't disappear? So you can use something like producer producing the event or in the blockchain producing the event and the consumer who is interested in the event consumes that event, processes that event successfully and then only acknowledges the event on the event broker. So you can have this explicit acknowledgement cycle that way you will ensure that your events are never lost. At least once the events are there in the message broker, they are never lost. On the other hand, you can also ensure that while producing the event in the first place, there are certain message delivery semantics like just once delivery or at least once delivery like they are there in Kafka or Rabbit MQ. So you can ensure those kind of semantics are enabled for your system so that on the producer side, the producer never misses the event to register them on the message broker and also on the consumer side, the consumer consumes it, successfully processes it and they don't lose it beforehand without processing it and then just normally crashing. I hope that answers the question. Awesome. So I suppose we are two minutes overdue. I'll just wait a minute more for any questions and then awesome. Awesome. Thank you. Thank you everyone. Thanks for the present. Thanks for attending. Looking forward to more interactions. Have a great day.