 Welcome everybody to our weekly Firefly community call. I'm excited to welcome Jim Zhang this week to talk about plans for integrating fabric into Firefly and how that will work together. And there's a little bit of code that's been written on that. And so, yeah, happy for Jim to share for the first part of today's community call. And then like we've been doing in the past, we'll open it up in the second half for questions, comments, discussion, either on fabric or on any other topic related to Firefly that people would like to discuss. So welcome. Thank you for being here and I will hand it over to Jim. Thanks, Nico. All right. Hi everybody. This is Jim. So today's topic is how to make a connector so that fabric-based blockchains can work with Firefly. As you know, Firefly historically started with the support for Ethereum. And of course, we always had fabric in the on the horizon. And this is when we're kicking off that effort. So in the past few weeks, on and off, I've been thinking about what it takes to build a quality connector that will serve the purpose of Firefly. And this is really built on top of the framework that one of my co-founder for Colorado, Peter Broadhurst, has created for Ethereum side. Even Ethereum fabric are very different kind of chains. The majority of the work that Peter did for Ethereum, and he was getting help from one of our protocol engineering leads, Vinod Damali. So both of them have created this awesome piece of work that's inside the Firefly-EathConnect repository. And a lot of this can be borrowed over to support fabric. So today's session is sort of half reviewing the framework that was done there, and then half how to plug in the fabric support. So let's get started. So we have three diagrams here. The first one is sort of high-level overview of the key components. And sort of just introduced the idea of a connector. What is a connector? Why do we need one? And what does it do? So if you had written any programs against fabric, you probably have come across one of the SDKs. So there's no GS-based SDK. There's Go SDK, and there's even the Java SDK. They're awesome. So they allow you to package up application data into transactions, send them to peers, and then send them to orderers so they can get mined into a block. That's great, but it's also a very programming-heavy kind of experience for a developer that just want to talk to a fabric network so their business data can get into a block. It's kind of a very large threshold of learning that you have to go through to even know what you're doing, beyond spending a lot of time understanding the fabric design itself. More often than not, when an enterprise developer approaches an enterprise application, in this case, a blockchain-based enterprise application, when they think of back-end, they think of APIs, right? But now we're saying, well, you have to learn this SDK. You have to learn all these calls that you need to make to different pieces of a fabric network to do your stuff. So what if we give them, instead, a RESTful API with clear endpoints and JSON payloads? So they can do all that much more easily. So that's what this is for, is first and foremost, a REST API that stands in front of a fabric network. So you will want to deploy this in front of your own peers and orderers. So your applications can talk to fabric through REST. But it's much more than just a REST server, because with Enterprise comes a lot of additional requirements in terms of key management, delivery of messages, and fault tolerance when some of the components may go offline, especially in the modern cloud-based deployment. So we need some guarantee of messages not getting lost. If, say, your node is going offline, you don't want your application to have to compensate for that and then re-send it. Instead, we want all the messages to be caught into a queue. So they will stay in the queue, and then they will be drip-fed into the node on the other side. So even if the node, for whatever reason, goes away before it comes back, all the transactions can continue to be submitted into the system, and they will just stay on the queue and waiting to be submitted to the blockchain. So, and then you also want to, since this is now sort of a async experience, you want to provide a storage of receipts, basically saving the transaction result so that they can be queried asynchronously. So that's what this diagram is trying to show. On the left-hand side, we have sort of high-level API capabilities. We've got to be able to manage identities, so users can call a post on the identities to create signing identities so that under the cover, we generate the client MSP crypto materials, get those to be registered and enrolled with Fabric CA so that they can be used later on to submit transactions. So that's the first piece. And second is we want at least two kinds of transaction submission. The obvious ones is I just want request response. My application doesn't really have a lot of transactions going through every day, so I'm okay just sending one at a time, wait for the whole thing to be completed, and then I get on the response the execution results. So that's just request and wait for response. So that's sort of the synchronous API that we've got to provide. But if your application is going to have many more transactions on a single second to be submitted and you want to submit those and then wait for the result, you don't want to be held, you don't want the thread to be held open, so you want a asynchronous experience. So we want to just acknowledge the submission and then track the completion of the transaction asynchronously and then store the result in some sort of database so that they can be queried. So the application will send and get the acknowledging the response that is being successfully sent and taken by this connector. And then it will sort of just keep holding on the result for that particular transaction by some sort of ID that we generate for them. So now we will have both sync synchronous and asynchronous kind of transaction submissions for different kinds of use case scenarios. And finally, we have to provide some sort of event streaming. This is very useful in several use cases. I know Fabric supports CouchDB based state store, which provides excellent query capability. But querying on the state database itself directly can be less efficient because the state has absolutely everything that the node catches. So query performance may be hindered if all you need is one piece of information, but you have to sort through thousands of other pieces that are happening in channels not related to you. And also, given the design of the schema that's catering to the Fabric internals, querying against this kind of database directly may not be as sufficient. So what you want to do is you want to build an offline transaction, excuse me, offline transaction cache that has just the transactions that your application are interested in. Based on the events that the Fabric node sends out when the transactions are mining to block. So you want a stream of events coming out of the pipe leading from the Fabric node, going into a sync and then you can take that and store it in your own database. That's dedicated to your application and you can query, you can set up a schema according to the application's needs and that will be the most favorable way to cache transaction results. So it'll be very useful for this connector to provide event streaming and not just catching the latest blocks, but you can tell this event streaming management, I want to start from block 0 or I want to start from block 1,000 or 10,000, whatever. And then going from that block on, give me all the events that are related to, by a regular expression kind of pattern, by name, whatever, right? So that's the kind of event streaming capabilities that we're looking for here. And then finally, in terms of delivering that to the client, we want both a WebSocket-based streaming channels, but maybe for certain scenarios, a WebHulk-based delivery of events might be useful. Maybe the client is deploying the zone that because of the networking conditions, WebSocket kind of long-living connections may not be optimal. A WebHulk-based endpoints, delivery events might be necessary there. So we want to kind of provide both. So I've covered sort of the high-level things. Now Kafka is going to be the queue that's going to be used to implement this queue so that for the async kind of submissions, we want all the messages to be sent to a Kafka queue. We want to use one, at least one topic. It turns out that we should have at least two topics that we'll cover in one of the next diagrams. But a Kafka topic on the per node basis, should be created. And then based on how many channels you may have, we can have different partitions dedicated to different channels. Because Kafka only guarantees a sequence or ordering on the partition basis. So we should use a partition to be paired with a channel. So all the transaction submissions, when they get submitted to the nodes, they don't go out of order. So that's sort of the high-level overview of the current thinking. Are there any questions from the audience at this point? I actually have a quick question, Jim. Sure. So you start off saying you're sharing a lot of similarities and at least thinking and design from Firefly Youth Connect with Firefly Youth Connect, it is possible to run with or without Kafka? Yes. In this design, does Firefly Connect, is it a requirement or is there another mode you can run in without Kafka as well? Yeah, that's a great question. So that's sort of a segue into our next diagram. Cool. So there are, unless there are other questions on the previous diagram or just continue here. Sounds like no. Okay. So there are three ways for a transaction to go through the system and each sort of life cycle requires its own components. So to directly answer your question, no, Kafka is not absolutely required. You can configure the system to only do synchronous, only do asynchronous or do both synchronous and asynchronous. And on the asynchronous side, we have also two kinds of asynchronous tracking of a transaction life cycle. We call it direct handler or Kafka based handler. We'll talk about the details, you know, why they're different. Why do we need both? But let's go through the synchronous life cycle and see what are the pieces we need to build to support that. So as a reminder, synchronous life cycle is as an application, I'm sending a transaction, you know, with a JSON payload to this endpoint, specifying my chain code, my parameters and my channel. And then I'm just going to wait so that when the response finally comes back, I expect to see the transaction results. After the transaction has been mined into a block. So to support this kind of life cycle, we want to build a synchronous dispatcher. So correspondingly, there should be a asynchronous dispatcher. So synchronous dispatcher will, you know, directly call this sort of the heart of the connector. We call it transaction processor. So it's able to translate a JSON payload and then understand what you're trying to do. What's the channel, what's the chain code method and what are the parameters and then package that into a payload that fabric nodes will understand. And then go through the SDK to submit that into the network. By the way, I haven't mentioned that we plan to use GoLan as a programming language to implement this. And because of that, we're going to build on top of the work that, you know, wrong, yeah, I think it's wrong. So this transaction processor will take the message and then change it into a transaction object and then submit that into the client and call execute method on the client. So that will submit the transaction into the client and then send that into the client. So that will submit the transaction into a fabric network, you know, first contacting the peers and then collecting all the endorsement and send it to the orderer, eventually getting the event to signal that the transaction has been mined into a block. So this transaction tracking will package the reply and then send it back to the dispatcher and then the response handler will give the response back to the client. So that's sort of the simplest way to have a request-response-based transaction lifecycle. So now let's talk about the async lifecycle now. So on submission, we want to immediately acknowledge, okay, we've got your message. You intend to invoke some transaction. We can do that for you and acknowledge back. Here's the ID you can use to keep track of this transaction to see where it's at on this journey to the blockchain and back. So a unique ID will be generated to the client in the response acknowledgement. So that this will represent this unique message throughout the journey. And next, we want something that will be responsible for keeping track of the whole lifecycle of this transaction. So first we'll talk about a direct handler. What we call a direct handler is basically an in-memory queue of transactions that are basically in-flight. So we'll use code routines each dedicated to a message or a transaction to track it all the way through. So we will maintain a in-memory in-flight transaction list. And you can tune, based on some tuning parameters, how many you'd like to be in-flight, based on your expected transaction load, you can dial it up or down. And based on how big your peer node is, what's the likely submission rate onto the node you can support. You can configure the number of transactions that should be in-flight. And then this will then, again, go through the transaction processor and then send it to the chain and listen for events. So all that is still the same. And finally, when a transaction is tracked to be confirmed and event is now fired, it'll go back to the transaction handler and say, okay, I've got the result and let's save it in the receipt store. So it'll be available for query. So that's all in-memory. Obviously, it's got no fault tolerance if the connector node goes away. In the cloud era, we always need to design off software to be as much fault tolerant as possible. So we want to also have a Kafka-based option. Obviously, this will be more expensive to configure, to deploy, and to operate, but it has to be there for the enterprise kind of usages. So what this is, is it's going to be a queue that'll cache all the transactions. And then on the other hand, the consumers will take them off of the queue, submit it to the transaction processor, again go through that lifecycle tracking. And eventually when it comes back, the event will also be threw back onto the queue into a different topic. So this is sort of the two topics per node thing we're talking about earlier. And then it'll be again picked off of that queue by a consumer and then process it and save it into the receipt store for query later. And the Kafka-based handler has a bit more details here. So we want two topics, one topic, one Kafka topic responsible for handling all the requests. So that's on the way in. This is all the requests that are taken from the submission. And then the consumer of this topic will then submit those to the transaction processors, which summits to the peer. And when eventually the event is emitted by the peer, we want to put the event onto a different topic. We call it receipts. And the consumer of that receipt will then process it and then saves it in the receipt store, which makes it available for query. So that's sort of the other details for the transaction lifecycle tracking. The last topic is event stream before we dive into that, like to pause here and see if there's any questions. Yeah. Jan Rock had a great question. What is the reason to prefer REST instead of GRPC part above streaming API security speed all solved already with GRPC? The streaming of GRPC? Sorry, I am. So I think the question is, why did we go with REST as the front door instead of GRPC? Yeah. I understand GRPC is more efficient, given its binary payload and is faster and also has full duplex kind of connections. But I think REST is just sort of the expected norm for application development. It's very likely when you talk to an enterprise solution developer, application developer, they would expect to REST more than GRPC. It's just much easier to use REST plus JSON rather than REST plus GRPC. But on the other hand, with certain systems, maybe GRPC, only GRPC can give you the kind of performance you expect. So we definitely welcome the community to contribute additional support for GRPC. I think that totally makes sense. So there is other input from... Just conscious, there was a second part of that was this idea that GRPC already handles the streaming. I think it's worth noting that Kafka in this architecture isn't being used for streaming as such. It's being used as a reliable, fault tolerant, persistent buffer. So the application can sort of say set and be done. And it will reliably become set. It's not just put it into a GRPC buffer and if it falls over, it has to recover, it has to use its own state to work out where it's gone. It's got it as far as Kafka, at least once delivery, means it's going to get into the GRCC buffer of fabric. So the intention here is taking away all of the significant complexity that having a GRPC buffer on the other end of something places on an application developer. It's not taking that complexity away. It's not about saying it's not valuable. It's valuable. It's just this kind of app. Basically, everyone has to build this. You want to do reliable streaming of transactions in the fabric. You need one of these. We know projects that are built here on fabric, Jim, don't we? So it's just, again, it's about just saying you don't need to build this, take it away from the application and develop a habit of worrying about this. And they just say, here's a JSON input of my transaction inputs. Get the signatures you need. Make it so. Yeah. Thanks for that additional input, Peter. So that's Peter Broders himself there. And I guess, just spending another minute on the possible relay question to Kafka. Why do we even need Kafka if fabric itself is a fault tolerant kind of design already? Well, this is mainly accounting for ingestion rate. So fabric is super fast, right? It can get up to a thousand per second, but you can totally have a system that can still overrun fabric even in that scenario. And I think Kafka is great for that, you know, can easily catch a million transactions per second. Plus it's also a enterprise friendly kind of components. A lot of enterprises have like direct hooks into Kafka to do that. And the other aspect with this is at least as of now, 2.3, you would have to contact, you know, a whole bunch of fabric nodes first, collect the information, and then submit the result to the fabric order. So there are many steps involved for the transaction to finally get into fabric. So all that is now taking care of behind the Kafka consumer. So the applications don't have to manage that. So I understand 2.4 is expected to have the submitting peer. So that's complexity sort of is taken care of, but still because of the fault tolerant and, you know, the rate of submission requirements, Kafka is going to be very valuable for a lot of scenarios. Thank you, Jim, Peter, just be mindful of time. We're about 30 minutes into the call. So and thank you to Jam for the great question and for volunteering to get involved to integrate GRPC. So I guess we didn't get to talk about event stream. We can, you know, do a few minutes in the next call, or, you know, we can engage through rocket chat. If you've gotten just a few more minutes, I think we can finish the topic here. We've kind of, we've led into the Q&A there. Sure. Thanks, Nicole. Okay. So the last bit of the architecture here is the event stream. This is very different than just listening, subscribing to events after you submitted a transaction. This is about maybe the chain has already gone through a million blocks and I'm a late joiner into the network. And I'd like to be replayed of all the events that has happened up to now. So, you know, I can build my application logic. And so I don't miss any of the significant historical events. So that's one scenario. You know, I'd like to be given all the other events that has happened in past plus listening to ongoing events. So that's one scenario. The other is again, what I mentioned, I like to hook sort of a pipe leading out of the fabric node into my own database so I can build my own query schema to serve my application's needs. So what we need to do here is first of all, we need a subscription manager. We need to ask the client what kind of events are you interested in. Is it all events, block events, transaction events or transaction events named in certain patterns. So I can create a subscription so that whenever any events that's matching this pattern come through, I'd like to be notified and I want to see the details of the event. And in terms of getting delivered the event details, I want to have the option of creating a long lived WebSocket connection or I can host a secure WebHook endpoint. So you can just send those to the WebHook by posting to this endpoint. So we have an event stream manager that'll allow the client to create these event streams that will be tied to one or more event subscriptions. And each event stream, when it kicked off, will pull from the blockchain, either from the latest blog or from the block zero or from certain block that you specify and replay all the events since then. Whenever each event is delivered, it'll look through the manager and see which client are interested in this event based on the subscription, find a configured way to deliver the event to that particular client and then send it there. So that's basically what the event stream capability does here. So I think that's all I had prepared in terms of the architecture. So now let's see if the audience has any questions. Cool, thank you, Kim. Yeah, we opened it up for discussion and questions, either on fabric or anything. Anything far fly up today. Okay, I'm going to take the screen share off for now. So I can see if people are raising their hands. Not everybody all at once here. Oh, sorry, a correction. I just remember it was alluding me, it was Troy, Troy Ronda from Secure Key. He's the creator of the SDK. Sorry, Troy, for some reason, I just couldn't remember the first name. BJ says, Jim, thanks for the insights. Is it possible to walk through an exception scenario? Ah, great question. Great question. Let me go back to the screen. All right. Okay, so I guess there are two kinds of except, well, at least two, maybe there are more. One is on submission for whatever reason, maybe the, this particular connector is being overrun or is having that working issue. You know, submission failed, right? So straightforward. The response says, sorry, I didn't take your transaction. Try again. More tricky is when something went wrong along the journey after it's been submitted. Let's say the, the fabric node itself is, is beyond reach at the moment. So that this, this execute call failed, right? So the transaction processor will have, you know, the goal routine that's fired off to, to keep track of that particular transaction will have retry logic. So that if it's a either four, four, five or three, that shows that the endpoint is not available at the point, at the moment, it'll just retry. So there's going to be some exponential backup kind of logic to, to make sure everybody don't retry all at once. And then it can also fail because the transaction itself is, is invalid. But that's, that doesn't really change the, the flow at all. So the transaction will still come through. And there's a event of the transaction fading and it'll be recorded in the receipt store as a failed transaction. So the application will query for that. So instead of seeing a successful transaction, we'll see a failed transaction and fabric is great in telling exactly how it failed. I think it's got like 30 or 40 different status code that tells you why the transaction failed and the application can, can take care of that by inspecting the error code. So I think that may well be all the exception scenarios. I don't know if VJ you had something more in mind. Sounds like that was, that was okay there. So I guess again, all questions really to far flies is very game here doesn't have to be fabric specific. Okay. Young has another question. When a task backlog will be created and where? How can I? Oh, ah. Okay. Good question. If you want to contribute. We're still in the early days of coding things up. I'm hoping the first code drop will happen in the next couple of days. So what I'm doing right now is just sort of setting up the basic skeleton of these components. So you can have a overview of all the pieces that are involved and how they relate to each other. And then over time we're filling the implementation. So that's where I am. I'm hoping to be able to drop the first commit soon and then I'll start creating a backlog of, you know, this piece needs to be implemented. That piece needs to be implemented. Hopefully soon. And. Yeah. I'm hoping to be able to do that. I'm hoping to be able to do that. I'm hoping to be able to do that. I'm hoping that GitHub issues will be the place to find all of those. We're trying to use GitHub as much as we can. Some of the projects that have been up there for a little bit longer have. A healthy backlog going out. But obviously this one is brand new. So it will take a little bit of time to fill that out. But that's, that's where they will be. And that's our goal to. Kind of document the. Both of the things we know we need to do or. We need to do that. And then we'll get into. The projects going as well. Yeah. And if you are really. Looking forward to starting this, I think the identity. The submitting identity. The sunny identity. Sorry. Peace might be a independent enough. Peace in all of this. So basically what we want is. component that can generate, can generate certificates, generate the client, a common connection profile, so that we can bootstrap a client MSP instance that then can be used to submit transactions. So the kind of APIs we need for that is post to identities, giving it a username, and then it'll call register and enroll with Fabric CA, and then it'll generate a wallet basically on the file system that can be later on used to load in the signing keys. I feel like that's a pretty independent piece of work that can be started right away. So if you're interested, we can discuss more in Rocket Chat. Yeah, we're definitely super excited to have more people get involved in this. So if you're interested, let's keep up the conversation and happy to meet more offline to talk about specifics on some of these things. Yeah, I hope to hear your voice in a future call. Definitely very excited to have you interested and want to contribute here. Hope we can talk soon over Rocket. All right, so I guess if there are no other questions, we can get back 60 minutes. Yeah, David's back. Last call for questions, I haven't seen any more pop up. Should we consider adding a process for dead letter Q on the copper side or leave it to the developers to implement that? That's a question for the DJ. Peter, did you have any input to that? So I guess we're going to refer to the Ethereum side and that's probably done it and had many, many, many millions of transactions gone through through this infrastructure and production over the last three years, because that, and the approach there is that if there's a problem processing a transaction and submitting it, but this infrastructure doesn't stop the world. It says, look, I'm going to developer, you're going to say, please send this transaction and I'm going to give you an identifier, right? I'm going to give you a placeholder for submission of that. I'm going to give you that straight away and I promise eventually to either give you a yes I've sent that transaction event or I promise to give you a yes for that event. But I don't promise that if you've done something wrong, which is where you need the execute, right? Which is if you've done something wrong, I'm going to try to like stop the world to not process anything after that. So if you as a submitter of transactions to Fabric, if you have a requirement that this transaction must be mined before this transaction, otherwise, like I've broken my on-chain state if I try to submit transaction number two before transaction number one is submitted, then you need to wait for it to go all the way through and come back as an application developer. The system will attempt and to sort of do that a few processing that would not be done in messaging. It tries to appear in time, it tries the lots of error handling, et cetera. Still have all done for various and still on the plate for Fabric around. Well, okay, I need to, I don't know, I need to get, I've looked at the policy for this channel and I need five signatures to get, I need five signatures because there's 10 parties and I need 50%. So I'm going to try and find five parties and I'm going to try and get signatures. There should be in the configuration and probably lots of configuration, policies on like how long am I going to try for? What if nobody's available? What if I can only get to four? How long do I wait for the fifth? And it should be, but the policy isn't, I'm just going to wait there, right? Because maybe this channel is just broken at the moment. It can't, there's actually only full notes up. There's not five notes up. The system should reliably try to appear in time. It crashes, it will restart, it will come back to a sensible point. It'll deal with making sure it sort of guides it through. But if it really can't do it after, I don't know, some really long time, like two minutes trying and it's just like, there's no way I can get the signatures needed. The approach so far has been to say, why you'll get a failure. And then in the far flight core side, the transaction objects then gets updated as a failure. And there's also associated with the transaction objects, associated with like if you were trying to send a message or you're doing a token transfer or whatever, there's a concept of an operation, which is like this bit went wrong. I couldn't submit the on-chain transaction as part of the token transfer, but maybe I sent the data offline. That operation then would go into a failed state. And the idea is then as an operator, you'd see that it's in a failed state. And the UI has operations like this is TBD, but on the UI side, you'd see operations in a broken state and you'd be able to resubmit them there. So, sorry, that was a bit of a long, long description, but like the model is not stopped the world, which we need to have to use. The model is, I'm going to do my best. I'm going to do like not, but you could have written the thousand lines of reliably trying to get transactions into fabric code yourself, but here's a community that's written the best job that they can do for you with reliability, crash fault tolerance, all the like. If it can't do it still, there are other cases where you might still have to get others back in your application. Yep, thanks for being definitely the expert on enterprise queues and messaging here. So yeah, if you guys have any other questions or fantastic questions so far, we're always available on the rocket chat. I just pasted the link there. The channel is called fly dash lap. So I'll always welcome any questions from that. Thank you. Thank you. Thanks for your questions. All right, nine minutes left. Any other questions? Good discussion today. This is a really exciting piece of work. And this component, just one last thing, this component, like once we've got two legs of the stool, like we caught us a little bit further behind, but I'm going to have a look at the quarter connect. There's a load of code there. There's my potential challenges to solve, but like we've got a theory and fabric at this layer. The intention then is that we can prove the layer on top and far fly, but isn't just like simple transactions and token transactions. It's any transaction by make just, you know, you can have custom transactions on top of the layer in the far fly cork and exists. And then there's been lots of questions since far fly. We started talking about it. TSE calls and the like of what about, what about my custom on chain logic? And we didn't want to declare success on that at the core layer just because we've got it at the theory layer because until you've proven something with two blockchain technologies, Jim's been making the point to me a lot. You can't prove an orchestration layer to work with Cosmodal protocols unless you've got two protocols. So I think this is really exciting. I'm really pleased to see the collaboration and the leadership here to just kind of get the fabric, the fabric leg of a stool on board. Yeah, absolutely. All right, you guys. Thanks so much for showing up today and hope to continue to engage with you guys on this piece of work through rocket chat, through email, whatever. And then on subsequent community calls, if you have questions, we'll be really happy to entertain. All right. Thank you, Jim. Thanks for the work you're doing on this. And thank you for presenting today. Really appreciate it. Thank you everybody for joining for this community call. I'm going to go ahead and stop the recording now and we'll wrap up. Thanks.