-
Notifications
You must be signed in to change notification settings - Fork 516
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
FABN-1722: export BlockDecoder for typescript definition #477
Conversation
fabric-common/types/index.d.ts
Outdated
@@ -245,6 +245,15 @@ export class Proposal extends ServiceAction { | |||
public compareProposalResponseResults(proposalResponses: any[]): boolean; | |||
} | |||
|
|||
export class BlockDecoder { | |||
constructor(); | |||
public decode(blockBuf: Buffer): fabproto6.common.Block; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jscode017 These methods are static according to the documentation, please update the type definitions accordingly. https://hyperledger.github.io/fabric-sdk-node/release-2.2/BlockDecoder.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, fix it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, cheers!
Signed-off-by: jsjs026 <[email protected]>
@jscode017 I'd also ask you to test if it actually works as expected, here's how you can do that manually as a one-off:
|
@petermetz |
@jscode017 Good enough for me. Of course the Fabric maintainers will provide the actual review but I wanted to help out with the preliminary as much as possible. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a tricky one. If you dig down into the protobuf definitions you will find that there are several points where properties are just Uint8Array. Often this byte data is actually a serialized protobuf structure. What the block decoder is doing is traversing down through the protobuf structure unpacking everything (including the nested serialized protobufs) into plain JavaScript objects, so the return values don't map exactly to any of the protobuf TypeScript definitions.
So, short of hand-crafting TypeScript definitions for the complete unpacked object structures, what can we do? Well the protobuf TypeScript definitions include both implementation classes (e.g. common.Block
) and accompanying interfaces (e.g. common.IBlock
). The class definitions include lots of protobuf-specific methods that definitely don't exist on the unpacked JavaScript objects returned from the block decoder, so they are the wrong thing to use. The interface definitions only define the protobuf properties so they are pretty close to what you get from the block decoder, with the caveat that they define some properties (like block.data.data
) as raw bytes.
Even the protobuf interface definitions are a lot better than no definitions so, unless you are really motivated to hand-craft type definitions for the entire object structure, I would suggest just using those instead of the protobuf implementation class definitions.
export class BlockDecoder { | ||
constructor(); | ||
public static decode(blockBuf: Buffer): fabproto6.common.Block; | ||
public static decodeBlock(blockProto: object): fabproto6.common.Block; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will take a fabproto6.common.IBlock
as its argument and version of that completely unpacked to a plain JavaScript object... or (a little confusingly) just return an fabproto6.common.IBlock
too
constructor(); | ||
public static decode(blockBuf: Buffer): fabproto6.common.Block; | ||
public static decodeBlock(blockProto: object): fabproto6.common.Block; | ||
public static decodeFilteredBlock(filteredBlockProto: object): fabproto6.protos.FilteredBlock; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Argument should be protos.IFilteredBlock
public static decode(blockBuf: Buffer): fabproto6.common.Block; | ||
public static decodeBlock(blockProto: object): fabproto6.common.Block; | ||
public static decodeFilteredBlock(filteredBlockProto: object): fabproto6.protos.FilteredBlock; | ||
public static decodeBlockWithPrivateData(BlockAndPrivateData: object): fabproto6.protos.BlockAndPrivateData; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Argument should be protos.IBlockAndPrivateData
@bestbeforetoday If you are interested I could recommend the thesayyn/protoc-gen-ts for generating the Typescript sources from the .proto files. I used it in a recent PR of mine to add gRPC support in the Cactus API server and was very happy with the way it solved my issues. PR: hyperledger-cacti/cacti#1190 An example of a proto message in TS (generated): https://github.com/hyperledger/cactus/blob/58a3a1c8c836f9b4a0fa09346cb9e42145cdb437/packages/cactus-cmd-api-server/src/main/typescript/generated/proto/protoc-gen-ts/models/health_check_response_pb.ts |
export class BlockDecoder { | ||
constructor(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The BlockDecoder only exposes static methods so it's not really intended to be used as class and instances created with new BlockDecoder()
. It might be worth defining it in TypeScript just as a namespace instead of a class with a constructor, and the static methods declared as functions within that namespace. Something like:
declare namespace BlockDecoder {
export function decode(blockBuf: Buffer): fabproto6.common.IBlock;
}
@petermetz Thanks for the pointer to thesayyn/protoc-gen-ts. I am currently using improbable-eng/ts-protoc-gen to extend protoc generated output to include TypeScript definitions in the new fabric-gateway client API, which is similar and seems to work fine. The fabric-protos package, which is published as part of this Node SDK, also includes TypeScript definitions for the generated protobuf implementations. These are generated using protobuf.js and are a little different in structure to the implementations generated by protoc, but functionally equivalent. It would be a big change to move away from protobuf.js. There are a few other options for gRPC/protobuf and TypeScript generation listed at badsyntax/grpc-js-typescript. The problem addressed by this PR is not the lack of TypeScript definitions for the protobufs, it's that the objects returned by |
This has been inactive for a long time and is not yet in a state to merge so I'll close it. Feel free to reopen if progress in made on the implementation. |
Signed-off-by: jsjs026 [email protected]
I refer to https://hyperledger.github.io/fabric-sdk-node/release-2.2/BlockDecoder.html
I am not sure I did it right, there are some questions/discussions.