Skip to content

Commit

Permalink
feat: core metadata type (#664)
Browse files Browse the repository at this point in the history
  • Loading branch information
aljo242 authored Aug 13, 2024
1 parent fb3f4de commit d886707
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 56 deletions.
38 changes: 38 additions & 0 deletions x/marketmap/types/tickermetadata/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package tickermetadata

import "encoding/json"

type AggregatorID struct {
// Venue is the name of the aggregator for which the ID is valid.
// E.g. `coingecko`, `cmc`
Venue string `json:"venue"`
// ID is the string ID of the Ticker's Base denom in the aggregator.
ID string `json:"ID"`
}

// NewAggregatorID returns a new AggregatorID instance.
func NewAggregatorID(venue, id string) AggregatorID {
return AggregatorID{
Venue: venue,
ID: id,
}
}

// MarshalAggregatorID returns the JSON byte encoding of the AggregatorID.
func MarshalAggregatorID(m AggregatorID) ([]byte, error) {
return json.Marshal(m)
}

// AggregatorIDFromJSONString returns an AggregatorID instance from a JSON string.
func AggregatorIDFromJSONString(jsonString string) (AggregatorID, error) {
var elem AggregatorID
err := json.Unmarshal([]byte(jsonString), &elem)
return elem, err
}

// AggregatorIDFromJSONBytes returns an AggregatorID instance from JSON bytes.
func AggregatorIDFromJSONBytes(jsonBytes []byte) (AggregatorID, error) {
var elem AggregatorID
err := json.Unmarshal(jsonBytes, &elem)
return elem, err
}
30 changes: 30 additions & 0 deletions x/marketmap/types/tickermetadata/common_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package tickermetadata_test

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/skip-mev/slinky/x/marketmap/types/tickermetadata"
)

func Test_UnmarshalAggregatorID(t *testing.T) {
t.Run("can marshal and unmarshal the same struct and values", func(t *testing.T) {
elem := tickermetadata.NewAggregatorID("coingecko", "id")

bz, err := tickermetadata.MarshalAggregatorID(elem)
require.NoError(t, err)

elem2, err := tickermetadata.AggregatorIDFromJSONBytes(bz)
require.NoError(t, err)
require.Equal(t, elem, elem2)
})

t.Run("can unmarshal a JSON string into a struct", func(t *testing.T) {
elemJSON := `{"venue":"coingecko","ID":"id"}`
elem, err := tickermetadata.AggregatorIDFromJSONString(elemJSON)
require.NoError(t, err)

require.Equal(t, tickermetadata.NewAggregatorID("coingecko", "id"), elem)
})
}
36 changes: 36 additions & 0 deletions x/marketmap/types/tickermetadata/core.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package tickermetadata

import "encoding/json"

// CoreMetadata is the Ticker.Metadata_JSON published to every Ticker in the x/marketmap module on core markets.
type CoreMetadata struct {
// AggregateIDs contains a list of AggregatorIDs associated with the ticker.
// This field may not be populated if no aggregator currently indexes this Ticker.
AggregateIDs []AggregatorID `json:"aggregate_ids"`
}

// NewCoreMetadata returns a new CoreMetadata instance.
func NewCoreMetadata(aggregateIDs []AggregatorID) CoreMetadata {
return CoreMetadata{
AggregateIDs: aggregateIDs,
}
}

// MarshalCoreMetadata returns the JSON byte encoding of the CoreMetadata.
func MarshalCoreMetadata(m CoreMetadata) ([]byte, error) {
return json.Marshal(m)
}

// CoreMetadataFromJSONString returns a CoreMetadata instance from a JSON string.
func CoreMetadataFromJSONString(jsonString string) (CoreMetadata, error) {
var elem CoreMetadata
err := json.Unmarshal([]byte(jsonString), &elem)
return elem, err
}

// CoreMetadataFromJSONBytes returns a CoreMetadata instance from JSON bytes.
func CoreMetadataFromJSONBytes(jsonBytes []byte) (CoreMetadata, error) {
var elem CoreMetadata
err := json.Unmarshal(jsonBytes, &elem)
return elem, err
}
51 changes: 51 additions & 0 deletions x/marketmap/types/tickermetadata/core_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package tickermetadata_test

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/skip-mev/slinky/x/marketmap/types/tickermetadata"
)

func Test_UnmarshalCoreMetadata(t *testing.T) {
t.Run("can marshal and unmarshal the same struct and values", func(t *testing.T) {
elem := tickermetadata.NewCoreMetadata(
[]tickermetadata.AggregatorID{
tickermetadata.NewAggregatorID("coingecko", "id"),
tickermetadata.NewAggregatorID("cmc", "id"),
},
)

bz, err := tickermetadata.MarshalCoreMetadata(elem)
require.NoError(t, err)

elem2, err := tickermetadata.CoreMetadataFromJSONBytes(bz)
require.NoError(t, err)
require.Equal(t, elem, elem2)
})

t.Run("can marshal and unmarshal the same struct and values with empty AggregatorIDs", func(t *testing.T) {
elem := tickermetadata.NewCoreMetadata(nil)

bz, err := tickermetadata.MarshalCoreMetadata(elem)
require.NoError(t, err)

elem2, err := tickermetadata.CoreMetadataFromJSONBytes(bz)
require.NoError(t, err)
require.Equal(t, elem, elem2)
})

t.Run("can unmarshal a JSON string into a struct", func(t *testing.T) {
elemJSON := `{"aggregate_ids":[{"venue":"coingecko","ID":"id"},{"venue":"cmc","ID":"id"}]}`
elem, err := tickermetadata.CoreMetadataFromJSONString(elemJSON)
require.NoError(t, err)

require.Equal(t, tickermetadata.NewCoreMetadata(
[]tickermetadata.AggregatorID{
tickermetadata.NewAggregatorID("coingecko", "id"),
tickermetadata.NewAggregatorID("cmc", "id"),
},
), elem)
})
}
35 changes: 0 additions & 35 deletions x/marketmap/types/tickermetadata/dydx.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,38 +45,3 @@ func DyDxFromJSONBytes(jsonBytes []byte) (DyDx, error) {
err := json.Unmarshal(jsonBytes, &elem)
return elem, err
}

type AggregatorID struct {
// Venue is the name of the aggregator for which the ID is valid.
// E.g. `coingecko`, `cmc`
Venue string `json:"venue"`
// ID is the string ID of the Ticker's Base denom in the aggregator.
ID string `json:"ID"`
}

// NewAggregatorID returns a new AggregatorID instance.
func NewAggregatorID(venue, id string) AggregatorID {
return AggregatorID{
Venue: venue,
ID: id,
}
}

// MarshalAggregatorID returns the JSON byte encoding of the AggregatorID.
func MarshalAggregatorID(m AggregatorID) ([]byte, error) {
return json.Marshal(m)
}

// AggregatorIDFromJSONString returns an AggregatorID instance from a JSON string.
func AggregatorIDFromJSONString(jsonString string) (AggregatorID, error) {
var elem AggregatorID
err := json.Unmarshal([]byte(jsonString), &elem)
return elem, err
}

// AggregatorIDFromJSONBytes returns an AggregatorID instance from JSON bytes.
func AggregatorIDFromJSONBytes(jsonBytes []byte) (AggregatorID, error) {
var elem AggregatorID
err := json.Unmarshal(jsonBytes, &elem)
return elem, err
}
21 changes: 0 additions & 21 deletions x/marketmap/types/tickermetadata/dydx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,24 +53,3 @@ func Test_UnmarshalDyDx(t *testing.T) {
), elem)
})
}

func Test_UnmarshalAggregatorID(t *testing.T) {
t.Run("can marshal and unmarshal the same struct and values", func(t *testing.T) {
elem := tickermetadata.NewAggregatorID("coingecko", "id")

bz, err := tickermetadata.MarshalAggregatorID(elem)
require.NoError(t, err)

elem2, err := tickermetadata.AggregatorIDFromJSONBytes(bz)
require.NoError(t, err)
require.Equal(t, elem, elem2)
})

t.Run("can unmarshal a JSON string into a struct", func(t *testing.T) {
elemJSON := `{"venue":"coingecko","ID":"id"}`
elem, err := tickermetadata.AggregatorIDFromJSONString(elemJSON)
require.NoError(t, err)

require.Equal(t, tickermetadata.NewAggregatorID("coingecko", "id"), elem)
})
}

0 comments on commit d886707

Please sign in to comment.