Add extra data to GetBlockTemplate request (#1995)

This commit is contained in:
Ori Newman 2022-03-31 20:12:33 +03:00 committed by GitHub
parent 21b82d7efc
commit cb65dae63d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 556 additions and 546 deletions

View File

@ -5,6 +5,7 @@ package appmessage
type GetBlockTemplateRequestMessage struct { type GetBlockTemplateRequestMessage struct {
baseMessage baseMessage
PayAddress string PayAddress string
ExtraData string
} }
// Command returns the protocol command string for the message // Command returns the protocol command string for the message
@ -13,9 +14,10 @@ func (msg *GetBlockTemplateRequestMessage) Command() MessageCommand {
} }
// NewGetBlockTemplateRequestMessage returns a instance of the message // NewGetBlockTemplateRequestMessage returns a instance of the message
func NewGetBlockTemplateRequestMessage(payAddress string) *GetBlockTemplateRequestMessage { func NewGetBlockTemplateRequestMessage(payAddress, extraData string) *GetBlockTemplateRequestMessage {
return &GetBlockTemplateRequestMessage{ return &GetBlockTemplateRequestMessage{
PayAddress: payAddress, PayAddress: payAddress,
ExtraData: extraData,
} }
} }

View File

@ -26,7 +26,7 @@ func HandleGetBlockTemplate(context *rpccontext.Context, _ *router.Router, reque
return nil, err return nil, err
} }
coinbaseData := &externalapi.DomainCoinbaseData{ScriptPublicKey: scriptPublicKey, ExtraData: []byte(version.Version())} coinbaseData := &externalapi.DomainCoinbaseData{ScriptPublicKey: scriptPublicKey, ExtraData: []byte(version.Version() + "/" + getBlockTemplateRequest.ExtraData)}
templateBlock, err := context.Domain.MiningManager().GetBlockTemplate(coinbaseData) templateBlock, err := context.Domain.MiningManager().GetBlockTemplate(coinbaseData)
if err != nil { if err != nil {

View File

@ -2,6 +2,7 @@ package main
import ( import (
nativeerrors "errors" nativeerrors "errors"
"github.com/kaspanet/kaspad/version"
"math/rand" "math/rand"
"sync/atomic" "sync/atomic"
"time" "time"
@ -187,7 +188,7 @@ func getBlockForMining(mineWhenNotSynced bool) (*externalapi.DomainBlock, *pow.S
func templatesLoop(client *minerClient, miningAddr util.Address, errChan chan error) { func templatesLoop(client *minerClient, miningAddr util.Address, errChan chan error) {
getBlockTemplate := func() { getBlockTemplate := func() {
template, err := client.GetBlockTemplate(miningAddr.String()) template, err := client.GetBlockTemplate(miningAddr.String(), "kaspaminer-"+version.Version())
if nativeerrors.Is(err, router.ErrTimeout) { if nativeerrors.Is(err, router.ErrTimeout) {
log.Warnf("Got timeout while requesting block template from %s: %s", client.Address(), err) log.Warnf("Got timeout while requesting block template from %s: %s", client.Address(), err)
reconnectErr := client.Reconnect() reconnectErr := client.Reconnect()

View File

@ -1,12 +1,13 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.26.0 // protoc-gen-go v1.25.0
// protoc v3.12.3 // protoc v3.12.3
// source: messages.proto // source: messages.proto
package protowire package protowire
import ( import (
proto "github.com/golang/protobuf/proto"
protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl" protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect" reflect "reflect"
@ -20,6 +21,10 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
) )
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type KaspadMessage struct { type KaspadMessage struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache

View File

@ -11,8 +11,7 @@ import (
// This is a compile-time assertion to ensure that this generated file // This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against. // is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion6
const _ = grpc.SupportPackageIsVersion7
// P2PClient is the client API for P2P service. // P2PClient is the client API for P2P service.
// //
@ -30,7 +29,7 @@ func NewP2PClient(cc grpc.ClientConnInterface) P2PClient {
} }
func (c *p2PClient) MessageStream(ctx context.Context, opts ...grpc.CallOption) (P2P_MessageStreamClient, error) { func (c *p2PClient) MessageStream(ctx context.Context, opts ...grpc.CallOption) (P2P_MessageStreamClient, error) {
stream, err := c.cc.NewStream(ctx, &P2P_ServiceDesc.Streams[0], "/protowire.P2P/MessageStream", opts...) stream, err := c.cc.NewStream(ctx, &_P2P_serviceDesc.Streams[0], "/protowire.P2P/MessageStream", opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -72,20 +71,13 @@ type P2PServer interface {
type UnimplementedP2PServer struct { type UnimplementedP2PServer struct {
} }
func (UnimplementedP2PServer) MessageStream(P2P_MessageStreamServer) error { func (*UnimplementedP2PServer) MessageStream(P2P_MessageStreamServer) error {
return status.Errorf(codes.Unimplemented, "method MessageStream not implemented") return status.Errorf(codes.Unimplemented, "method MessageStream not implemented")
} }
func (UnimplementedP2PServer) mustEmbedUnimplementedP2PServer() {} func (*UnimplementedP2PServer) mustEmbedUnimplementedP2PServer() {}
// UnsafeP2PServer may be embedded to opt out of forward compatibility for this service. func RegisterP2PServer(s *grpc.Server, srv P2PServer) {
// Use of this interface is not recommended, as added methods to P2PServer will s.RegisterService(&_P2P_serviceDesc, srv)
// result in compilation errors.
type UnsafeP2PServer interface {
mustEmbedUnimplementedP2PServer()
}
func RegisterP2PServer(s grpc.ServiceRegistrar, srv P2PServer) {
s.RegisterService(&P2P_ServiceDesc, srv)
} }
func _P2P_MessageStream_Handler(srv interface{}, stream grpc.ServerStream) error { func _P2P_MessageStream_Handler(srv interface{}, stream grpc.ServerStream) error {
@ -114,10 +106,7 @@ func (x *p2PMessageStreamServer) Recv() (*KaspadMessage, error) {
return m, nil return m, nil
} }
// P2P_ServiceDesc is the grpc.ServiceDesc for P2P service. var _P2P_serviceDesc = grpc.ServiceDesc{
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var P2P_ServiceDesc = grpc.ServiceDesc{
ServiceName: "protowire.P2P", ServiceName: "protowire.P2P",
HandlerType: (*P2PServer)(nil), HandlerType: (*P2PServer)(nil),
Methods: []grpc.MethodDesc{}, Methods: []grpc.MethodDesc{},
@ -148,7 +137,7 @@ func NewRPCClient(cc grpc.ClientConnInterface) RPCClient {
} }
func (c *rPCClient) MessageStream(ctx context.Context, opts ...grpc.CallOption) (RPC_MessageStreamClient, error) { func (c *rPCClient) MessageStream(ctx context.Context, opts ...grpc.CallOption) (RPC_MessageStreamClient, error) {
stream, err := c.cc.NewStream(ctx, &RPC_ServiceDesc.Streams[0], "/protowire.RPC/MessageStream", opts...) stream, err := c.cc.NewStream(ctx, &_RPC_serviceDesc.Streams[0], "/protowire.RPC/MessageStream", opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -190,20 +179,13 @@ type RPCServer interface {
type UnimplementedRPCServer struct { type UnimplementedRPCServer struct {
} }
func (UnimplementedRPCServer) MessageStream(RPC_MessageStreamServer) error { func (*UnimplementedRPCServer) MessageStream(RPC_MessageStreamServer) error {
return status.Errorf(codes.Unimplemented, "method MessageStream not implemented") return status.Errorf(codes.Unimplemented, "method MessageStream not implemented")
} }
func (UnimplementedRPCServer) mustEmbedUnimplementedRPCServer() {} func (*UnimplementedRPCServer) mustEmbedUnimplementedRPCServer() {}
// UnsafeRPCServer may be embedded to opt out of forward compatibility for this service. func RegisterRPCServer(s *grpc.Server, srv RPCServer) {
// Use of this interface is not recommended, as added methods to RPCServer will s.RegisterService(&_RPC_serviceDesc, srv)
// result in compilation errors.
type UnsafeRPCServer interface {
mustEmbedUnimplementedRPCServer()
}
func RegisterRPCServer(s grpc.ServiceRegistrar, srv RPCServer) {
s.RegisterService(&RPC_ServiceDesc, srv)
} }
func _RPC_MessageStream_Handler(srv interface{}, stream grpc.ServerStream) error { func _RPC_MessageStream_Handler(srv interface{}, stream grpc.ServerStream) error {
@ -232,10 +214,7 @@ func (x *rPCMessageStreamServer) Recv() (*KaspadMessage, error) {
return m, nil return m, nil
} }
// RPC_ServiceDesc is the grpc.ServiceDesc for RPC service. var _RPC_serviceDesc = grpc.ServiceDesc{
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var RPC_ServiceDesc = grpc.ServiceDesc{
ServiceName: "protowire.RPC", ServiceName: "protowire.RPC",
HandlerType: (*RPCServer)(nil), HandlerType: (*RPCServer)(nil),
Methods: []grpc.MethodDesc{}, Methods: []grpc.MethodDesc{},

View File

@ -1,12 +1,13 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.26.0 // protoc-gen-go v1.25.0
// protoc v3.12.3 // protoc v3.12.3
// source: p2p.proto // source: p2p.proto
package protowire package protowire
import ( import (
proto "github.com/golang/protobuf/proto"
protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl" protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect" reflect "reflect"
@ -20,6 +21,10 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
) )
// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4
type RequestAddressesMessage struct { type RequestAddressesMessage struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache

View File

@ -454,6 +454,7 @@ See: SubmitBlockRequestMessage
| Field | Type | Label | Description | | Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- | | ----- | ---- | ----- | ----------- |
| payAddress | [string](#string) | | Which kaspa address should the coinbase block reward transaction pay into | | payAddress | [string](#string) | | Which kaspa address should the coinbase block reward transaction pay into |
| extraData | [string](#string) | | |

View File

@ -152,6 +152,7 @@ message SubmitBlockResponseMessage{
message GetBlockTemplateRequestMessage{ message GetBlockTemplateRequestMessage{
// Which kaspa address should the coinbase block reward transaction pay into // Which kaspa address should the coinbase block reward transaction pay into
string payAddress = 1; string payAddress = 1;
string extraData = 2;
} }
message GetBlockTemplateResponseMessage{ message GetBlockTemplateResponseMessage{

View File

@ -15,6 +15,7 @@ func (x *KaspadMessage_GetBlockTemplateRequest) toAppMessage() (appmessage.Messa
func (x *KaspadMessage_GetBlockTemplateRequest) fromAppMessage(message *appmessage.GetBlockTemplateRequestMessage) error { func (x *KaspadMessage_GetBlockTemplateRequest) fromAppMessage(message *appmessage.GetBlockTemplateRequestMessage) error {
x.GetBlockTemplateRequest = &GetBlockTemplateRequestMessage{ x.GetBlockTemplateRequest = &GetBlockTemplateRequestMessage{
PayAddress: message.PayAddress, PayAddress: message.PayAddress,
ExtraData: message.ExtraData,
} }
return nil return nil
} }
@ -25,6 +26,7 @@ func (x *GetBlockTemplateRequestMessage) toAppMessage() (appmessage.Message, err
} }
return &appmessage.GetBlockTemplateRequestMessage{ return &appmessage.GetBlockTemplateRequestMessage{
PayAddress: x.PayAddress, PayAddress: x.PayAddress,
ExtraData: x.ExtraData,
}, nil }, nil
} }

View File

@ -3,8 +3,8 @@ package rpcclient
import "github.com/kaspanet/kaspad/app/appmessage" import "github.com/kaspanet/kaspad/app/appmessage"
// GetBlockTemplate sends an RPC request respective to the function's name and returns the RPC server's response // GetBlockTemplate sends an RPC request respective to the function's name and returns the RPC server's response
func (c *RPCClient) GetBlockTemplate(miningAddress string) (*appmessage.GetBlockTemplateResponseMessage, error) { func (c *RPCClient) GetBlockTemplate(miningAddress, extraData string) (*appmessage.GetBlockTemplateResponseMessage, error) {
err := c.rpcRouter.outgoingRoute().Enqueue(appmessage.NewGetBlockTemplateRequestMessage(miningAddress)) err := c.rpcRouter.outgoingRoute().Enqueue(appmessage.NewGetBlockTemplateRequestMessage(miningAddress, extraData))
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -252,7 +252,7 @@ func runDAATest(t *testing.T, testName string, runDuration time.Duration,
} }
func fetchBlockForMining(t *testing.T, rpcClient *rpcclient.RPCClient) *externalapi.DomainBlock { func fetchBlockForMining(t *testing.T, rpcClient *rpcclient.RPCClient) *externalapi.DomainBlock {
getBlockTemplateResponse, err := rpcClient.GetBlockTemplate(miningAddress) getBlockTemplateResponse, err := rpcClient.GetBlockTemplate(miningAddress, "")
if err != nil { if err != nil {
t.Fatalf("GetBlockTemplate: %s", err) t.Fatalf("GetBlockTemplate: %s", err)
} }

View File

@ -64,7 +64,7 @@ func realMain() error {
defer rpcClient.Disconnect() defer rpcClient.Disconnect()
// Mine block that its timestamp is one second after the genesis timestamp. // Mine block that its timestamp is one second after the genesis timestamp.
blockTemplate, err := rpcClient.GetBlockTemplate(miningAddress.EncodeAddress()) blockTemplate, err := rpcClient.GetBlockTemplate(miningAddress.EncodeAddress(), "")
if err != nil { if err != nil {
return err return err
} }
@ -174,7 +174,7 @@ func generateAddress() (util.Address, error) {
} }
func mineBlock(rpcClient *rpc.Client, miningAddress util.Address) error { func mineBlock(rpcClient *rpc.Client, miningAddress util.Address) error {
blockTemplate, err := rpcClient.GetBlockTemplate(miningAddress.EncodeAddress()) blockTemplate, err := rpcClient.GetBlockTemplate(miningAddress.EncodeAddress(), "")
if err != nil { if err != nil {
return err return err
} }
@ -191,7 +191,7 @@ func mineBlock(rpcClient *rpc.Client, miningAddress util.Address) error {
} }
func mineTips(numOfTips int, miningAddress util.Address, rpcClient *rpc.Client) error { func mineTips(numOfTips int, miningAddress util.Address, rpcClient *rpc.Client) error {
blockTemplate, err := rpcClient.GetBlockTemplate(miningAddress.EncodeAddress()) blockTemplate, err := rpcClient.GetBlockTemplate(miningAddress.EncodeAddress(), "")
if err != nil { if err != nil {
return err return err
} }

View File

@ -98,7 +98,7 @@ func submitAnAmountOfTransactionsToTheMempool(t *testing.T, rpcClient *rpcclient
} }
func mineBlockAndGetCoinbaseTransaction(t *testing.T, rpcClient *rpcclient.RPCClient) *externalapi.DomainTransaction { func mineBlockAndGetCoinbaseTransaction(t *testing.T, rpcClient *rpcclient.RPCClient) *externalapi.DomainTransaction {
getBlockTemplateResponse, err := rpcClient.GetBlockTemplate(payAddress) getBlockTemplateResponse, err := rpcClient.GetBlockTemplate(payAddress, "")
if err != nil { if err != nil {
t.Fatalf("GetBlockTemplate: %+v", err) t.Fatalf("GetBlockTemplate: %+v", err)
} }

View File

@ -185,7 +185,7 @@ func mineOnTips(client *rpc.Client) (appmessage.RejectReason, error) {
return appmessage.RejectReasonNone, err return appmessage.RejectReasonNone, err
} }
template, err := client.GetBlockTemplate(addr.String()) template, err := client.GetBlockTemplate(addr.String(), "")
if err != nil { if err != nil {
return appmessage.RejectReasonNone, err return appmessage.RejectReasonNone, err
} }

View File

@ -115,7 +115,7 @@ func TestIBDWithPruning(t *testing.T) {
} }
// Checking that the syncee can generate block templates before resolving the virtual // Checking that the syncee can generate block templates before resolving the virtual
_, err = syncee.rpcClient.GetBlockTemplate(syncee.miningAddress) _, err = syncee.rpcClient.GetBlockTemplate(syncee.miningAddress, "")
if err != nil { if err != nil {
t.Fatalf("Error getting block template: %+v", err) t.Fatalf("Error getting block template: %+v", err)
} }
@ -210,7 +210,7 @@ var currentMockTimestamp int64 = 0
// between every two blocks. This is done to avoid the timestamp threshold validation // between every two blocks. This is done to avoid the timestamp threshold validation
// of ibd-with-headers-proof // of ibd-with-headers-proof
func mineNextBlockWithMockTimestamps(t *testing.T, harness *appHarness, rd *rand.Rand) *externalapi.DomainBlock { func mineNextBlockWithMockTimestamps(t *testing.T, harness *appHarness, rd *rand.Rand) *externalapi.DomainBlock {
blockTemplate, err := harness.rpcClient.GetBlockTemplate(harness.miningAddress) blockTemplate, err := harness.rpcClient.GetBlockTemplate(harness.miningAddress, "")
if err != nil { if err != nil {
t.Fatalf("Error getting block template: %+v", err) t.Fatalf("Error getting block template: %+v", err)
} }

View File

@ -11,7 +11,7 @@ import (
) )
func mineNextBlock(t *testing.T, harness *appHarness) *externalapi.DomainBlock { func mineNextBlock(t *testing.T, harness *appHarness) *externalapi.DomainBlock {
blockTemplate, err := harness.rpcClient.GetBlockTemplate(harness.miningAddress) blockTemplate, err := harness.rpcClient.GetBlockTemplate(harness.miningAddress, "integration")
if err != nil { if err != nil {
t.Fatalf("Error getting block template: %+v", err) t.Fatalf("Error getting block template: %+v", err)
} }