From 321e727328a86bcfdb8f5bef164e7d50e698408b Mon Sep 17 00:00:00 2001 From: cam-schultz <78878559+cam-schultz@users.noreply.github.com> Date: Fri, 26 Jul 2024 18:11:15 -0500 Subject: [PATCH] ACP 118 reference implementation (#3218) --- network/p2p/handler.go | 8 ++ proto/pb/sdk/sdk.pb.go | 159 +++++++++++++++++++++++++-- proto/sdk/sdk.proto | 18 +++ vms/avm/network/network.go | 6 +- vms/platformvm/network/network.go | 6 +- vms/platformvm/vm_regression_test.go | 3 +- 6 files changed, 183 insertions(+), 17 deletions(-) diff --git a/network/p2p/handler.go b/network/p2p/handler.go index f3f4bebf4acc..3223ed362229 100644 --- a/network/p2p/handler.go +++ b/network/p2p/handler.go @@ -15,6 +15,14 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" ) +// Standardized identifiers for application protocol handlers +const ( + TxGossipHandlerID = iota + AtomicTxGossipHandlerID + // SignatureRequestHandlerID is specified in ACP-118: https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/118-warp-signature-request + SignatureRequestHandlerID +) + var ( _ Handler = (*NoOpHandler)(nil) _ Handler = (*TestHandler)(nil) diff --git a/proto/pb/sdk/sdk.pb.go b/proto/pb/sdk/sdk.pb.go index d6f458984a80..a1289d391032 100644 --- a/proto/pb/sdk/sdk.pb.go +++ b/proto/pb/sdk/sdk.pb.go @@ -169,6 +169,117 @@ func (x *PushGossip) GetGossip() [][]byte { return nil } +// SignatureRequest is an AppRequest message type for requesting +// a BLS signature over a Warp message, as defined in ACP-118: +// https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/118-warp-signature-request +type SignatureRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Warp message to be signed + Message []byte `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + // Justification for the message + Justification []byte `protobuf:"bytes,2,opt,name=justification,proto3" json:"justification,omitempty"` +} + +func (x *SignatureRequest) Reset() { + *x = SignatureRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_sdk_sdk_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SignatureRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignatureRequest) ProtoMessage() {} + +func (x *SignatureRequest) ProtoReflect() protoreflect.Message { + mi := &file_sdk_sdk_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignatureRequest.ProtoReflect.Descriptor instead. +func (*SignatureRequest) Descriptor() ([]byte, []int) { + return file_sdk_sdk_proto_rawDescGZIP(), []int{3} +} + +func (x *SignatureRequest) GetMessage() []byte { + if x != nil { + return x.Message + } + return nil +} + +func (x *SignatureRequest) GetJustification() []byte { + if x != nil { + return x.Justification + } + return nil +} + +// SignatureRespnose is an AppResponse message type for providing +// a requested BLS signature over a Warp message, as defined in ACP-118: +// https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/118-warp-signature-request +type SignatureResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // BLS signature over the Warp message + Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *SignatureResponse) Reset() { + *x = SignatureResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_sdk_sdk_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SignatureResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignatureResponse) ProtoMessage() {} + +func (x *SignatureResponse) ProtoReflect() protoreflect.Message { + mi := &file_sdk_sdk_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignatureResponse.ProtoReflect.Descriptor instead. +func (*SignatureResponse) Descriptor() ([]byte, []int) { + return file_sdk_sdk_proto_rawDescGZIP(), []int{4} +} + +func (x *SignatureResponse) GetSignature() []byte { + if x != nil { + return x.Signature + } + return nil +} + var File_sdk_sdk_proto protoreflect.FileDescriptor var file_sdk_sdk_proto_rawDesc = []byte{ @@ -182,11 +293,19 @@ var file_sdk_sdk_proto_rawDesc = []byte{ 0x6f, 0x73, 0x73, 0x69, 0x70, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x22, 0x24, 0x0a, 0x0a, 0x50, 0x75, 0x73, 0x68, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0c, 0x52, 0x06, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, - 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x73, 0x64, 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x0c, 0x52, 0x06, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x22, 0x52, 0x0a, 0x10, 0x53, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x6a, 0x75, 0x73, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, + 0x6a, 0x75, 0x73, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x31, 0x0a, + 0x11, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, + 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, + 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x73, 0x64, 0x6b, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -201,11 +320,13 @@ func file_sdk_sdk_proto_rawDescGZIP() []byte { return file_sdk_sdk_proto_rawDescData } -var file_sdk_sdk_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_sdk_sdk_proto_msgTypes = make([]protoimpl.MessageInfo, 5) var file_sdk_sdk_proto_goTypes = []interface{}{ (*PullGossipRequest)(nil), // 0: sdk.PullGossipRequest (*PullGossipResponse)(nil), // 1: sdk.PullGossipResponse (*PushGossip)(nil), // 2: sdk.PushGossip + (*SignatureRequest)(nil), // 3: sdk.SignatureRequest + (*SignatureResponse)(nil), // 4: sdk.SignatureResponse } var file_sdk_sdk_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type @@ -257,6 +378,30 @@ func file_sdk_sdk_proto_init() { return nil } } + file_sdk_sdk_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SignatureRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_sdk_sdk_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SignatureResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -264,7 +409,7 @@ func file_sdk_sdk_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_sdk_sdk_proto_rawDesc, NumEnums: 0, - NumMessages: 3, + NumMessages: 5, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/sdk/sdk.proto b/proto/sdk/sdk.proto index 3f91f23efdfe..d4eea3d5d085 100644 --- a/proto/sdk/sdk.proto +++ b/proto/sdk/sdk.proto @@ -16,3 +16,21 @@ message PullGossipResponse { message PushGossip { repeated bytes gossip = 1; } + +// SignatureRequest is an AppRequest message type for requesting +// a BLS signature over a Warp message, as defined in ACP-118: +// https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/118-warp-signature-request +message SignatureRequest { + // Warp message to be signed + bytes message = 1; + // Justification for the message + bytes justification = 2; +} + +// SignatureRespnose is an AppResponse message type for providing +// a requested BLS signature over a Warp message, as defined in ACP-118: +// https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/118-warp-signature-request +message SignatureResponse { + // BLS signature over the Warp message + bytes signature = 1; +} diff --git a/vms/avm/network/network.go b/vms/avm/network/network.go index ed565b1bd578..15d3dc79d156 100644 --- a/vms/avm/network/network.go +++ b/vms/avm/network/network.go @@ -19,8 +19,6 @@ import ( "github.com/ava-labs/avalanchego/vms/avm/txs/mempool" ) -const txGossipHandlerID = 0 - var ( _ common.AppHandler = (*Network)(nil) _ validators.Connector = (*Network)(nil) @@ -68,7 +66,7 @@ func New( config.MaxValidatorSetStaleness, ) txGossipClient := p2pNetwork.NewClient( - txGossipHandlerID, + p2p.TxGossipHandlerID, p2p.WithValidatorSampling(validators), ) txGossipMetrics, err := gossip.NewMetrics(registerer, "tx") @@ -157,7 +155,7 @@ func New( appRequestHandler: validatorHandler, } - if err := p2pNetwork.AddHandler(txGossipHandlerID, txGossipHandler); err != nil { + if err := p2pNetwork.AddHandler(p2p.TxGossipHandlerID, txGossipHandler); err != nil { return nil, err } diff --git a/vms/platformvm/network/network.go b/vms/platformvm/network/network.go index a43bb4b99aa1..c821c8272511 100644 --- a/vms/platformvm/network/network.go +++ b/vms/platformvm/network/network.go @@ -21,8 +21,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" ) -const TxGossipHandlerID = 0 - var errMempoolDisabledWithPartialSync = errors.New("mempool is disabled partial syncing") type Network struct { @@ -66,7 +64,7 @@ func New( config.MaxValidatorSetStaleness, ) txGossipClient := p2pNetwork.NewClient( - TxGossipHandlerID, + p2p.TxGossipHandlerID, p2p.WithValidatorSampling(validators), ) txGossipMetrics, err := gossip.NewMetrics(registerer, "tx") @@ -154,7 +152,7 @@ func New( appRequestHandler: validatorHandler, } - if err := p2pNetwork.AddHandler(TxGossipHandlerID, txGossipHandler); err != nil { + if err := p2pNetwork.AddHandler(p2p.TxGossipHandlerID, txGossipHandler); err != nil { return nil, err } diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index c505f9b1a9e1..035573fd8ae8 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -37,7 +37,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/metrics" - "github.com/ava-labs/avalanchego/vms/platformvm/network" "github.com/ava-labs/avalanchego/vms/platformvm/reward" "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/state" @@ -2441,7 +2440,7 @@ func TestValidatorSetRaceCondition(t *testing.T) { require.NoError(err) appRequestBytes := p2p.PrefixMessage( - p2p.ProtocolPrefix(network.TxGossipHandlerID), + p2p.ProtocolPrefix(p2p.TxGossipHandlerID), protocolAppRequestBytest, )