diff --git a/cmd/monero/get_block_template.go b/cmd/monero/get_block_template.go new file mode 100644 index 0000000..2094aa0 --- /dev/null +++ b/cmd/monero/get_block_template.go @@ -0,0 +1,45 @@ +package main + +import ( + "encoding/json" + "fmt" + "os" + + "github.com/cirocosta/go-monero/pkg/daemonrpc" +) + +type GetBlockTemplateCommand struct { + WalletAddress string `long:"wallet-address" required:"true" description:"address of wallet to receive coinbase txns if block is successfully mined"` + ReserveSize uint `long:"reserve-size" required:"true" description:"reserve size"` +} + +func (c *GetBlockTemplateCommand) Execute(_ []string) error { + client, err := daemonrpc.NewClient(options.Address, + daemonrpc.WithHTTPClient(daemonrpc.NewHTTPClient(options.Verbose)), + ) + if err != nil { + return fmt.Errorf("new client for '%s': %w", options.Address, err) + } + + resp, err := client.GetBlockTemplate(c.WalletAddress, c.ReserveSize) + if err != nil { + return fmt.Errorf("get block count: %w", err) + } + + encoder := json.NewEncoder(os.Stdout) + encoder.SetIndent(" ", " ") + + if err := encoder.Encode(resp); err != nil { + return fmt.Errorf("encode: %w", err) + } + + return nil +} + +func init() { + parser.AddCommand("get-block-template", + "Get a block template on which mining a new block", + "Get a block template on which mining a new block", + &GetBlockTemplateCommand{}, + ) +} diff --git a/pkg/daemonrpc/methods.go b/pkg/daemonrpc/methods.go index b170c35..65ba62b 100644 --- a/pkg/daemonrpc/methods.go +++ b/pkg/daemonrpc/methods.go @@ -8,13 +8,15 @@ const ( MethodGetBlockTemplate = "get_block_template" ) -type GetBlockCountResponse struct { +type GetBlockCountResult struct { Count uint64 `json:"count"` Status string `json:"status"` } -func (c *Client) GetBlockCount() (*GetBlockCountResponse, error) { - resp := &GetBlockCountResponse{} +func (c *Client) GetBlockCount() (*GetBlockCountResult, error) { + var ( + resp = &GetBlockCountResult{} + ) if err := c.JsonRPC(MethodGetBlockCount, nil, resp); err != nil { return nil, fmt.Errorf("get: %w", err) @@ -24,11 +26,42 @@ func (c *Client) GetBlockCount() (*GetBlockCountResponse, error) { } func (c *Client) OnGetBlockHash(height uint64) (string, error) { - var resp string + var ( + resp = "" + params = []uint64{height} + ) - if err := c.JsonRPC(MethodOnGetBlockHash, []uint64{height}, &resp); err != nil { + if err := c.JsonRPC(MethodOnGetBlockHash, params, &resp); err != nil { return "", fmt.Errorf("get: %w", err) } return resp, nil } + +type GetBlockTemplateResult struct { + BlockhashingBlob string `json:"blockhashing_blob"` + BlocktemplateBlob string `json:"blocktemplate_blob"` + Difficulty int64 `json:"difficulty"` + ExpectedReward int64 `json:"expected_reward"` + Height int `json:"height"` + PrevHash string `json:"prev_hash"` + ReservedOffset int `json:"reserved_offset"` + Status string `json:"status"` + Untrusted bool `json:"untrusted"` +} + +func (c *Client) GetBlockTemplate(walletAddress string, reserveSize uint) (*GetBlockTemplateResult, error) { + var ( + resp = &GetBlockTemplateResult{} + params = map[string]interface{}{ + "wallet_address": walletAddress, + "reserve_size": reserveSize, + } + ) + + if err := c.JsonRPC(MethodGetBlockTemplate, params, resp); err != nil { + return nil, fmt.Errorf("get: %w", err) + } + + return resp, nil +}