Skip to content
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

Datalayer RPCs #141

Merged
merged 11 commits into from
Aug 2, 2024
2 changes: 1 addition & 1 deletion pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ type PoolConfig struct {
// FarmerConfig farmer configuration section
type FarmerConfig struct {
FullNodePeers []Peer `yaml:"full_node_peers"`
PoolPublicKeys []string `yaml:"pool_public_keys"` // @TODO test if the !!set notation parses correctly
PoolPublicKeys types.WonkySet `yaml:"pool_public_keys"`
XCHTargetAddress string `yaml:"xch_target_address,omitempty"`
StartRPCServer bool `yaml:"start_rpc_server"`
EnableProfiler bool `yaml:"enable_profiler"`
Expand Down
2 changes: 1 addition & 1 deletion pkg/config/initial-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ farmer:
- host: *self_hostname
port: 8444

pool_public_keys: []
pool_public_keys: !!set {}

# Replace this with a real receive address
# xch_target_address: txch102gkhhzs60grx7cfnpng5n6rjecr89r86l5s8xux2za8k820cxsq64ssdg
Expand Down
173 changes: 173 additions & 0 deletions pkg/rpc/datalayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"net/http"

"github.com/chia-network/go-chia-libs/pkg/rpcinterface"
"github.com/chia-network/go-chia-libs/pkg/types"
)

// DataLayerService encapsulates data layer RPC methods
Expand Down Expand Up @@ -36,3 +37,175 @@ func (s *DataLayerService) GetVersion(opts *GetVersionOptions) (*GetVersionRespo

return r, resp, nil
}

// DatalayerGetSubscriptionsOptions options for get_subscriptions
type DatalayerGetSubscriptionsOptions struct{}

// DatalayerGetSubscriptionsResponse response for get_subscriptions
type DatalayerGetSubscriptionsResponse struct {
Response
StoreIDs []string `json:"store_ids"`
}

// GetSubscriptions is just an alias for Subscriptions, since the CLI command is get_subscriptions
// Makes this easier to find
func (s *DataLayerService) GetSubscriptions(opts *DatalayerGetSubscriptionsOptions) (*DatalayerGetSubscriptionsResponse, *http.Response, error) {
return s.Subscriptions(opts)
}

// Subscriptions calls the subscriptions endpoint to list all subscriptions
func (s *DataLayerService) Subscriptions(opts *DatalayerGetSubscriptionsOptions) (*DatalayerGetSubscriptionsResponse, *http.Response, error) {
request, err := s.NewRequest("subscriptions", opts)
if err != nil {
return nil, nil, err
}

r := &DatalayerGetSubscriptionsResponse{}

resp, err := s.Do(request, r)
if err != nil {
return nil, resp, err
}

return r, resp, nil
}

// DatalayerGetOwnedStoresOptions Options for get_owned_stores
type DatalayerGetOwnedStoresOptions struct{}

// DatalayerGetOwnedStoresResponse Response for get_owned_stores
type DatalayerGetOwnedStoresResponse struct {
Response
StoreIDs []string `json:"store_ids"`
}

// GetOwnedStores RPC endpoint get_owned_stores
func (s *DataLayerService) GetOwnedStores(opts *DatalayerGetOwnedStoresOptions) (*DatalayerGetOwnedStoresResponse, *http.Response, error) {
request, err := s.NewRequest("get_owned_stores", opts)
if err != nil {
return nil, nil, err
}

r := &DatalayerGetOwnedStoresResponse{}

resp, err := s.Do(request, r)
if err != nil {
return nil, resp, err
}

return r, resp, nil
}

// DatalayerGetMirrorsOptions Options for get_mirrors
type DatalayerGetMirrorsOptions struct {
ID string `json:"id"` // Hex String
}

// DatalayerGetMirrorsResponse Response from the get_mirrors RPC
type DatalayerGetMirrorsResponse struct {
Response
Mirrors []types.DatalayerMirror `json:"mirrors"`
}

// GetMirrors lists the mirrors for the given datalayer store
func (s *DataLayerService) GetMirrors(opts *DatalayerGetMirrorsOptions) (*DatalayerGetMirrorsResponse, *http.Response, error) {
request, err := s.NewRequest("get_mirrors", opts)
if err != nil {
return nil, nil, err
}

r := &DatalayerGetMirrorsResponse{}

resp, err := s.Do(request, r)
if err != nil {
return nil, resp, err
}

return r, resp, nil
}

// DatalayerDeleteMirrorOptions options for delete_mirror RPC call
type DatalayerDeleteMirrorOptions struct {
CoinID string `json:"coin_id"` // hex string
Fee uint64 `json:"fee"` // not required
}

// DatalayerDeleteMirrorResponse response data for delete_mirror
type DatalayerDeleteMirrorResponse struct {
Response
}

// DeleteMirror deletes a datalayer mirror
func (s *DataLayerService) DeleteMirror(opts *DatalayerDeleteMirrorOptions) (*DatalayerDeleteMirrorResponse, *http.Response, error) {
request, err := s.NewRequest("delete_mirror", opts)
if err != nil {
return nil, nil, err
}

r := &DatalayerDeleteMirrorResponse{}

resp, err := s.Do(request, r)
if err != nil {
return nil, resp, err
}

return r, resp, nil
}

// DatalayerAddMirrorOptions options for delete_mirror RPC call
type DatalayerAddMirrorOptions struct {
ID string `json:"id"` // hex string datastore ID
URLs []string `json:"urls"`
Amount uint64 `json:"amount"`
Fee uint64 `json:"fee"`
}

// DatalayerAddMirrorResponse response data for add_mirror
type DatalayerAddMirrorResponse struct {
Response
}

// AddMirror deletes a datalayer mirror
func (s *DataLayerService) AddMirror(opts *DatalayerAddMirrorOptions) (*DatalayerAddMirrorResponse, *http.Response, error) {
request, err := s.NewRequest("add_mirror", opts)
if err != nil {
return nil, nil, err
}

r := &DatalayerAddMirrorResponse{}

resp, err := s.Do(request, r)
if err != nil {
return nil, resp, err
}

return r, resp, nil
}

// DatalayerUnsubscribeOptions options for unsubscribing to a datastore
type DatalayerUnsubscribeOptions struct {
ID string `json:"id"` // hex string datastore id
RetainData bool `json:"retain"`
}

// DatalayerUnsubscribeResponse response data for unsubscribe
type DatalayerUnsubscribeResponse struct {
Response
}

// Unsubscribe deletes a datalayer mirror
func (s *DataLayerService) Unsubscribe(opts *DatalayerUnsubscribeOptions) (*DatalayerUnsubscribeResponse, *http.Response, error) {
request, err := s.NewRequest("unsubscribe", opts)
if err != nil {
return nil, nil, err
}

r := &DatalayerUnsubscribeResponse{}

resp, err := s.Do(request, r)
if err != nil {
return nil, resp, err
}

return r, resp, nil
}
15 changes: 15 additions & 0 deletions pkg/types/datalayer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package types

import (
"github.com/samber/mo"
)

// DatalayerMirror represents a single mirror for a data store
type DatalayerMirror struct {
CoinID Bytes32 `json:"coin_id"`
LauncherID Bytes32 `json:"launcher_id"`
Amount uint64 `json:"amount"`
URLs []string `json:"urls"`
Ours bool `json:"ours"`
ConfirmedAtHeight mo.Option[uint32] `json:"confirmed_at_height"`
}
31 changes: 31 additions & 0 deletions pkg/types/wonkyset.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package types

import (
"fmt"
)

// WonkySet is just an alias for map[string]string that will unmarshal correctly from the empty forms {} and []
// In chia-blockchain, the default for some sets was incorrectly [] in the initial config
// so this ensures compatability with both ways the empty values could show up
type WonkySet map[string]string

// UnmarshalYAML implements the yaml.Unmarshaler interface.
func (ws *WonkySet) UnmarshalYAML(unmarshal func(interface{}) error) error {
// Attempt to unmarshal into a slice of strings.
var sliceErr error
var mapErr error
var slice []string
if sliceErr = unmarshal(&slice); sliceErr == nil {
*ws = make(map[string]string)
return nil
}

// Attempt to unmarshal into a map.
var m map[string]string
if mapErr = unmarshal(&m); mapErr != nil {
return fmt.Errorf("failed to unmarshal as either string slice of map: slice err: %s | map err: %s", sliceErr.Error(), mapErr.Error())
cmmarslender marked this conversation as resolved.
Show resolved Hide resolved
}

*ws = m
return nil
}
45 changes: 45 additions & 0 deletions pkg/types/wonkyset_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package types_test

import (
"testing"

"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"

"github.com/chia-network/go-chia-libs/pkg/config"
)

// TestWonkySet_UnmarshalYAML ensures that this will unmarshal both empty list [] and dict {} into empty map[string]string
// And also ensures an actual !!set as it would show up in the yaml unmarshals correctly
func TestWonkySet_UnmarshalYAML(t *testing.T) {
var yamlWithList = []byte(`
farmer:
pool_public_keys: []
`)
var yamlWithDict = []byte(`
farmer:
pool_public_keys: {}
`)

var yamlWithData = []byte(`
farmer:
pool_public_keys: !!set
abc123: null
456xyz: null
`)

cfg := &config.ChiaConfig{}
err := yaml.Unmarshal(yamlWithList, cfg)
assert.NoError(t, err)
assert.Len(t, cfg.Farmer.PoolPublicKeys, 0)

cfg = &config.ChiaConfig{}
err = yaml.Unmarshal(yamlWithDict, cfg)
assert.NoError(t, err)
assert.Len(t, cfg.Farmer.PoolPublicKeys, 0)

cfg = &config.ChiaConfig{}
err = yaml.Unmarshal(yamlWithData, cfg)
assert.NoError(t, err)
assert.Len(t, cfg.Farmer.PoolPublicKeys, 2)
}