-
Notifications
You must be signed in to change notification settings - Fork 49
CoAP Gateway for Hyperledger Fabric #66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Added a new RFC proposing a CoAP gateway to enable IoT and resource-constrained devices to interact with Fabric networks. - Defined lightweight, UDP-based communication using CoAP protocol with DTLS security for encrypted and authenticated connections. - Outlined the gateway architecture as an optional peer service that acts as a protocol converter. - Included four core endpoints: /evaluate, /endorse, /submit, and /events for transaction operations. - Provided integration with existing Fabric MSP for device identity management and X.509 certificate authentication. - Ensured backward compatibility by making the CoAP gateway an optional feature that doesn't affect existing gRPC gateway functionality. - Added comprehensive error handling with appropriate CoAP response codes and security model integration. - Included example use cases for supply chain tracking and smart city applications with IoT sensors. Signed-off-by: bernardo.figueiredo <bernardo.figueiredo@voidsoftware.com>
|
@yacovm @denyeart @manish-sethi @tock-ibm @ale-linux @C0rWin @andrew-coleman @bestbeforetoday @satota2 @pfi79 This is the proper PR related to the RFC proposes adding a CoAP gateway to Fabric for IoT device integration, with the proper checks passed. Please review and provide feedback. |
|
Thank you for your proposes.
|
|
The peer Gateway service provides a CommitStatus method in addition to the Evaluate, Endorse, Submit and ChaincodeEvents methods that you have modelled. This is used to check the eventual status of a previously submitted transaction. See the protocol buffer definition and this overview of the Gateway transaction flow. From the RFC description, it sounds like your submit is doing both the Submit and CommitStatus operations. |
|
@pfi79 Thank you for your questions. Here are the answers.
Yes, the CoAP gateway will reuse the existing proto files from the fabric-protos project. This ensures that the CoAP gateway maintains full compatibility with the existing Fabric gateway ecosystem. This is stated in the RFC: The RFC specifically mentions using:
The CoAP gateway will unmarshal incoming CoAP payloads into these standard protobuf messages, process them through the existing gateway logic, and marshal responses back to CoAP format.
The current transaction processing model will be maintained. The RFC states: And in the cold chain example: This means:
The IoT device will use the same transaction preparation logic as any other Fabric client, creating properly formatted protobuf messages that the CoAP gateway can directly forward to the existing Fabric infrastructure. The CoAP gateway simply acts forwarding the already-prepared and signed protobuf messages to the existing Fabric infrastructure. This maintains the security model where IoT devices are treated as first-class Fabric identities with their own certificates and signing capabilities, ensuring no degradation of Fabric's security properties.
While the RFC doesn't include specific code examples, I can provide a conceptual example based on the design described. This represents the planned implementation approach rather than existing code. Here's what the implementation would look like using the existing Fabric protobuf definitions This implementation demonstrates how the CoAP gateway would integrate with existing Fabric infrastructure while providing the lightweight protocol interface needed for IoT devices.
You raise an excellent point about the Fabric SDK being archived. Let me clarify the context of these references in the RFC. The RFC uses "Fabric SDK" in two specific contexts, neither of which recommends its use: Conceptual Analogy (Line 57): The RFC correctly focuses on the current
If you prefer, we could update these references to use more generic terms like "Fabric client library" or "existing Fabric client" or "Fabric Gateway" to avoid any confusion about the deprecated SDK. However, the current references serve their intended purpose of explaining historical context and providing conceptual clarity without recommending the use of deprecated libraries. |
|
@bestbeforetoday Thank you for your question. Here is the answer.
You're correct! The current Fabric Gateway service includes a To ensure the CoAP gateway provides the same functionality as the existing gRPC gateway, I propose adding a fifth endpoint to the RFC. The current CoAP gateway RFC models four endpoints:
My proposal is to update the RFC with the following changes:
This would enable IoT devices to both submit transactions and check their status. |
- Standardizes the document structure to improve readability - Standardizes heading levels and adds consistent spacing between sections - The technical content remains unchanged, but the overall document is now more consistent and easier to read. Signed-off-by: bernardo.figueiredo <bernardo.figueiredo@voidsoftware.com>
- Add /commit-status endpoint with SignedCommitStatusRequest/CommitStatusResponse - Clarify submit behavior: waits for orderer submission - Update endpoint count and API documentation for complete gateway parity - Add CommitStatusHandler to core components Enables IoT devices to check transaction status asynchronously after submission. Signed-off-by: bernardo.figueiredo <bernardo.figueiredo@voidsoftware.com>
|
Following discussions, I have created a presentation that summarizes the goals and design of this RFC. I am sharing the presentation material on the Hyperledger Fabric mailing list to kick off wider community discussion. Please find the mailing list thread here: Link to the Mailing List Announcement |
Thank you for your presentation.
|
|
Hi @pfi79 , Thank you for your review. Your comments regarding the separation of security identities and the long-term maintenance strategy can significantly strengthened this proposal. I agree that the best path forward involves adopting two key architectural changes to ensure the CoAP Gateway adheres to Hyperledger Fabric's security and maintenance standards. I have drafted the specific changes below and plan to commit them to the RFC. Could you confirm if this proposed resolution addresses your concerns and if you are aligned with this direction before I finalize the updated RFC text? 1. Resolution for Security Model Confusion (DTLS vs. Fabric Identity)You have a point regarding separating the transport identity from the signing identity is the most secure and robust approach. We will be moving from a unified certificate model to a Dual-Certificate Model. This addresses the security separation and clarifies the two-stage authentication process within the gateway: Proposed New Flow:
Key Updates to RFC Text:The "Guide-level explanation," "Protocol and Security," and "Client Authentication" sections will be updated to explicitly describe this two-stage process and the requirement for two certificates. 2. Resolution for Protocol Generation and MaintainabilityI agree that a manual implementation for Protobuf message handling creates an unacceptable maintenance burden. Proposed Solution:
|
|
Yes, I agree with what you wrote.
In fact, leads what you came up with to what is in fabric. Therefore, it minimizes changes.
I agree with almost everything. But most likely, you will not have a choice of the order of "file generation". Because the files are generated in the I understand that creating a utility that would work with |
@pfi79 I completely agree with the concern regarding the file generation order and the maintenance overhead of a custom Instead, I am proposing a Descriptor-Driven Approach. This approach leverages the protobuf descriptors that are already compiled into the How it solves the maintenance issue:
Why this approach ?
Minimal Maintenance Burden
Generic Implementation
Compile-Time Safety
This satisfies the need for a 'simpler' solution that doesn't break the existing build flow while being essentially maintenance-free as the API evolves. |
Thank you, and by and large, I support your initiative. There are some minor nuances left for me. When I suggested considering generation at the fabric-protos level, I was also thinking about generating functions for the client. At least for tests, and at the maximum for easier creation of clients to fabric via CoAP. |
@pfi79 Thank you for the feedback. To address the concerns regarding the need for easy client/test creation, I am proposing a Descriptor-Driven Approach as the primary solution, complemented by a Two-Layer Client Architecture that lives entirely within the This bypasses the Generic Descriptor-Driven ClientThe core client uses the // coapgateway/inner_client.go
func (c *GenericClient) InvokeUnary(ctx context.Context, methodName string, req, resp proto.Message) error {
// 1. Look up method info from the embedded descriptors (not hardcoded)
methodInfo, err := c.registry.GetMethod(methodName)
if err != nil { return err }
// 2. The path is built dynamically (e.g., /rpc/gateway.Gateway/Endorse)
path := fmt.Sprintf("/rpc/%s/%s", c.registry.ServiceName, methodName)
// 3. Marshal/Send/Unmarshal using the standard proto library
payload, _ := proto.Marshal(req)
coapResp, err := c.conn.Post(ctx, path, message.AppOctetStream, payload)
// ... error handling and unmarshaling ...
return proto.Unmarshal(coapResp.Body(), resp)
}High-Level Type-Safe WrapperTo fulfill the goal of making it easy for clients and tests to use CoAP, I’ve added a thin wrapper that provides the specific functions you mentioned (e.g., Endorse, Submit). // coapgateway/client.go - The high-level wrapper for users/tests
type GatewayClient struct {
inner *GenericClient // The descriptor-driven engine
}
// Named functions provide the "generated" feel without the generator complexity
func (c *GatewayClient) Endorse(ctx context.Context, req *gw.EndorseRequest) (*gw.EndorseResponse, error) {
resp := &gw.EndorseResponse{}
// inner.InvokeUnary handles the URI pathing and marshaling generically
err := c.inner.InvokeUnary(ctx, "Endorse", req, resp)
return resp, err
}
func (c *GatewayClient) Submit(ctx context.Context, req *gw.SubmitRequest) (*gw.SubmitResponse, error) {
resp := &gw.SubmitResponse{}
err := c.inner.InvokeUnary(ctx, "Submit", req, resp)
return resp, err
}Because this wrapper is 'logic-less', it only needs to be updated if a brand-new RPC method is added to the Gateway. Given the stability of the Gateway API, this is a much smaller burden than maintaining a custom
The primary focus remains the Descriptor-Driven Approach, providing a maintenance-free server. The two-layer client is a complementary addition to ensure a quality developer experience. Does this approach satisfy both the architectural maintenance requirements and the need for a high-quality client/test DX? |
The fact is that the client should not import packages from the fabric repository. If there is even a small chance sometime in the future that a new method will be added to Gateway, I kindly ask you to consider your solution for this option. |
|
@pfi79 After reflecting on your feedback and the broader adoption goals, it's clear that providing an easy, proto-based client generation option is essential for the success of this feature. Without automated client generation, we risk:
Given these considerations, I propose revisiting the protoc Generation Utility approach, specifically: a code generation plugin that integrates directly into the Proposed Solution:
|
I fully support you. |
Key changes:
- Automated client generation via protoc plugin
- Clarify dual-certificate model follows standard Fabric pattern
- Update endpoints to RPC-style (/rpc/gateway.Gateway/{Method})
- Add implementation details (peer lifecycle, context flow, error mapping)
- Add developer experience section with code examples
- Remove duplicate MSP configuration (uses peer-level config)
- Streamline security explanations to emphasize consistency with gRPC
Signed-off-by: bernardo.figueiredo <bernardo.figueiredo@voidsoftware.com>
Technical Update: Standardized Generation & Security ModelBased on consensus with @pfi79 , I have pivoted the RFC to a static generation model and clarified the security handshake. These changes ensure the CoAP Gateway follows the existing Fabric toolchain without manual maintenance. 1. Toolchain Integration (
|
|
Hi, I've just been catching up on the discussions related to fabric-protos. I like the idea of adding support for resource constrained devices, and extending the fabric-protos build pipeline to generate a coap client implementation seems really interesting but I don't think that the coap client code should be added to the existing The generated go, java and node bindings currently only contain what's defined in the protobuf definitions, which is a good thing and in my opinion should not change. I think it would be surprising for a project that only requires the go bindings to get a coap client implementation as well. (All the actual client implementations are in separate projects.) Using a new protoc plugin in the fabric-protos build to generate a client implementation definitely sounds interesting but it probably only makes sense if the code can be 100% generated, which I think is the case based on...
If not, you're swapping having to manually update a client project, with maintaining a protoc plugin somewhere and having to manually update the client implementation anyway. (Mixing generated and hand written code can cause its own problems.) |
I may have misunderstood you. fabric-protos-go-apev2 is used by both fabric and clients and libraries that implement changecodes. If you're worried that there won't be such an implementation for other languages (node and java). There has already been such a precedent, and I am primarily interested in the implementation on go. In the future, it will be possible to open questions about the implementation of this in other languages. If you are worried that the generation will take place directly in fabric-protos-go-apiv2. No way. All changes are only in fabric-protos. How do I make a plugin? There are options here. They can be discussed. Of course, I want it to be official as protocol-gen-go. But I think it won't be a big deal if the plugin is customized first. |
|
Similar to James, I am nervous of adding CoAP bindings to fabric-protos-go-apiv2. This would force an unnecessary dependency on existing (gRPC-based) consumers: chaincode, admin SDK, client API and all the client applications that use those APIs. Could CoAP bindings (generated in fabric-protos from the same protobuf definitions) not be published to a sister repository for client consumption? For example, a fabric-coap-go repository. |
I don't understand why you're afraid of this. Could you explain in more detail? |
The thing is that the implementation of CoAP directly depends on proto files. Let me show you with a simpler example, I recently did an exercise (adding the rest api if we already have grpc) Now let's look at the code that was generated - *.pb.gw.go. It directly calls functions from the *_grpc.pb.go file. As a rule, such files are located nearby. For example, here is the code for peer/peer.proto (see Yes, we don't need the rest api yet, but in CoaP-API I would like to see the same brevity and conciseness of the generated code. Therefore, it should be located next to the *_grpc.pb.go file. You can not generate a file for all proto files, but for now only for the desired gateway.proto |
|
In the case of fabric-protos, generation is divided by programming languages (go, java, and node). |
|
The The language bindings can be used for all kinds of things, such as extracting information from blocks received via mqtt for example. If the current bindings start pulling in unrelated and unwanted dependencies, it's likely that people would stop using them and go back to generating bindings themselves, which wouldn't be great. Using the fabric-protos repo to generate other modules like a coap client sounds good to me if that's possible, and may even provide a blueprint that other use cases could follow, but the output should be separate to the currently published bindings. @bestbeforetoday's suggestion of a Perhaps moving
I'm not worried about coap not covering all the same languages as the existing bindings. (As an aside I'm hoping that fabric-protos will eventually expand to cover bindings for more languages, such as C# and Rust.) |
|
I will ask one more clarifying question. How do you feel about the protocol-gen-grpc-gateway plugin? If we need to create a rest api based on proto files in fabric, how do you see it? Will you record this in a separate repository? The protocol-gen-grpc-gateway plugin requires direct access to proto files and the direct presence (i.e., they should be nearby) of _grpc.pb.go files. And there will be dependencies too "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" and "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" Try to do what you suggest for CoAP, do for gateway.
Are you afraid that in fabric-protos-go-apiv2, a new dependency type will appear in go.mod "github.com/...../CoaP "
I consider your example with fabric-gaytway incorrect. It uses client functions from gateway/gateway_grpc.pb.go go Here are the dependencies he's dragging in: That is, I can now redirect your claims to already existing entities. |
For the output, yes, definitely, a RESTful Gateway API should be published as a new module, not included in the existing For the build, no, it makes sense to go in |
Thank you. Could you provide a link to your version? Maybe then I'll have no complaints about your option. |


This RFC proposes the addition of a Constrained Application Protocol (CoAP) gateway to Hyperledger Fabric. The goal is to enable IoT and resource-constrained devices to interact with Fabric networks using a lightweight, UDP-based protocol. The CoAP gateway will provide a simplified interface for submitting transactions, evaluating chaincode, and receiving events, maintaining security through DTLS encryption and certificate-based authentication.
The current Hyperledger Fabric gRPC gateway has limitations for IoT and resource-constrained devices due to limited memory, processing power, and network bandwidth requirements. Many IoT deployments use UDP-based networks or have unreliable connectivity, making gRPC/HTTP2 impractical. The CoAP gateway addresses these limitations by providing lightweight, UDP-based communication with DTLS security for encrypted and authenticated connections.
Key features include:
The CoAP gateway will be implemented as an optional peer service that acts as a protocol converter, translating CoAP requests into appropriate gRPC calls while maintaining the same security model and transaction lifecycle as the existing Fabric gateway.
This enhancement enables new use cases such as supply chain tracking with IoT sensors, smart city applications, and other scenarios requiring direct integration of resource-constrained devices with Fabric networks.
Signed-off-by: Bernardo Figueiredo bernardo.figueiredo@voidsoftware.com
Co-authored-by: Marco Ferreira marco.ferreira@voidsoftware.com
Co-authored-by: Marco Cova marco.cova@voidsoftware.com