diff --git a/extras/jsonrpc/daemon_types.go b/extras/jsonrpc/daemon_types.go index d4b68a1..f856137 100644 --- a/extras/jsonrpc/daemon_types.go +++ b/extras/jsonrpc/daemon_types.go @@ -11,7 +11,7 @@ import ( "github.com/lbryio/lbry.go/v2/extras/errors" "github.com/lbryio/lbry.go/v2/stream" - schema "github.com/lbryio/lbry.go/v2/schema/claim" + schema "github.com/lbryio/lbry.go/v2/schema/stake" lbryschema "github.com/lbryio/types/v2/go" "github.com/shopspring/decimal" diff --git a/go.mod b/go.mod index 21e7d87..af2c37a 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/kr/pretty v0.1.0 // indirect github.com/lbryio/ozzo-validation v0.0.0-20170323141101-d1008ad1fd04 - github.com/lbryio/types v0.0.0-20191009145016-1bb8107e04f8 + github.com/lbryio/types v0.0.0-20201019032447-f0b4476ef386 github.com/lyoshenka/bencode v0.0.0-20180323155644-b7abd7672df5 github.com/mitchellh/mapstructure v1.1.2 github.com/nlopes/slack v0.6.0 diff --git a/go.sum b/go.sum index fe2479b..e0134b2 100644 --- a/go.sum +++ b/go.sum @@ -63,12 +63,15 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lbryio/lbry.go v1.1.2 h1:Dyxc+glT/rVWJwHfIf7vjlPYYbjzrQz5ARmJd5Hp69c= github.com/lbryio/lbrycrd.go v0.0.0-20200203050410-e1076f12bf19 h1:/zWD8dVIl7bV1TdJWqPqy9tpqixzX2Qxgit48h3hQcY= github.com/lbryio/lbrycrd.go v0.0.0-20200203050410-e1076f12bf19/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/lbryio/ozzo-validation v0.0.0-20170323141101-d1008ad1fd04 h1:Nze+C2HbeKvhjI/kVn+9Poj/UuEW5sOQxcsxqO7L3GI= github.com/lbryio/ozzo-validation v0.0.0-20170323141101-d1008ad1fd04/go.mod h1:fbG/dzobG8r95KzMwckXiLMHfFjZaBRQqC9hPs2XAQ4= github.com/lbryio/types v0.0.0-20191009145016-1bb8107e04f8 h1:jSNW/rK6DQsz7Zh+iv1zR384PeQdHt0gS4hKY17tkuM= github.com/lbryio/types v0.0.0-20191009145016-1bb8107e04f8/go.mod h1:CG3wsDv5BiVYQd5i1Jp7wGsaVyjZTJshqXeWMVKsISE= +github.com/lbryio/types v0.0.0-20201019032447-f0b4476ef386 h1:JOQkGpeCM9FWkEHRx+kRPqySPCXElNW1em1++7tVS4M= +github.com/lbryio/types v0.0.0-20201019032447-f0b4476ef386/go.mod h1:CG3wsDv5BiVYQd5i1Jp7wGsaVyjZTJshqXeWMVKsISE= github.com/lyoshenka/bencode v0.0.0-20180323155644-b7abd7672df5 h1:mG83tLXWSRdcXMWfkoumVwhcCbf3jHF9QKv/m37BkM0= github.com/lyoshenka/bencode v0.0.0-20180323155644-b7abd7672df5/go.mod h1:H0aPCWffGOaDcjkw1iB7W9DVLp6GXmfcJY/7YZCWPA4= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= diff --git a/lbrycrd/channel.go b/lbrycrd/channel.go index 5da97ee..67f75b9 100644 --- a/lbrycrd/channel.go +++ b/lbrycrd/channel.go @@ -3,11 +3,12 @@ package lbrycrd import ( "github.com/btcsuite/btcd/btcec" "github.com/lbryio/lbry.go/v2/extras/errors" - c "github.com/lbryio/lbry.go/v2/schema/claim" + "github.com/lbryio/lbry.go/v2/schema/keys" + c "github.com/lbryio/lbry.go/v2/schema/stake" pb "github.com/lbryio/types/v2/go" ) -func NewChannel() (*c.ClaimHelper, *btcec.PrivateKey, error) { +func NewChannel() (*c.StakeHelper, *btcec.PrivateKey, error) { claimChannel := new(pb.Claim_Channel) channel := new(pb.Channel) claimChannel.Channel = channel @@ -19,21 +20,21 @@ func NewChannel() (*c.ClaimHelper, *btcec.PrivateKey, error) { if err != nil { return nil, nil, errors.Err(err) } - pubkeyBytes, err := c.PublicKeyToDER(privateKey.PubKey()) + pubkeyBytes, err := keys.PublicKeyToDER(privateKey.PubKey()) if err != nil { return nil, nil, errors.Err(err) } - helper := c.ClaimHelper{Claim: pbClaim} + helper := c.StakeHelper{Claim: pbClaim} helper.Version = c.NoSig - helper.GetChannel().PublicKey = pubkeyBytes - helper.Tags = []string{} + helper.Claim.GetChannel().PublicKey = pubkeyBytes + helper.Claim.Tags = []string{} coverSrc := new(pb.Source) - helper.GetChannel().Cover = coverSrc - helper.Languages = []*pb.Language{} + helper.Claim.GetChannel().Cover = coverSrc + helper.Claim.Languages = []*pb.Language{} thumbnailSrc := new(pb.Source) - helper.Thumbnail = thumbnailSrc - helper.Locations = []*pb.Location{} + helper.Claim.Thumbnail = thumbnailSrc + helper.Claim.Locations = []*pb.Location{} return &helper, privateKey, nil } diff --git a/lbrycrd/claim.go b/lbrycrd/claim.go index aab72f1..57ca4d7 100644 --- a/lbrycrd/claim.go +++ b/lbrycrd/claim.go @@ -4,14 +4,14 @@ import ( "encoding/hex" "github.com/lbryio/lbry.go/v2/extras/errors" - c "github.com/lbryio/lbry.go/v2/schema/claim" + c "github.com/lbryio/lbry.go/v2/schema/stake" pb "github.com/lbryio/types/v2/go" "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/wire" ) -func NewImageStreamClaim() (*c.ClaimHelper, error) { +func NewImageStreamClaim() (*c.StakeHelper, error) { streamClaim := new(pb.Claim_Stream) stream := new(pb.Stream) image := new(pb.Stream_Image) @@ -23,12 +23,12 @@ func NewImageStreamClaim() (*c.ClaimHelper, error) { pbClaim := new(pb.Claim) pbClaim.Type = streamClaim - helper := c.ClaimHelper{Claim: pbClaim} + helper := c.StakeHelper{Claim: pbClaim} return &helper, nil } -func NewVideoStreamClaim() (*c.ClaimHelper, error) { +func NewVideoStreamClaim() (*c.StakeHelper, error) { streamClaim := new(pb.Claim_Stream) stream := new(pb.Stream) video := new(pb.Stream_Video) @@ -39,12 +39,12 @@ func NewVideoStreamClaim() (*c.ClaimHelper, error) { pbClaim := new(pb.Claim) pbClaim.Type = streamClaim - helper := c.ClaimHelper{Claim: pbClaim} + helper := c.StakeHelper{Claim: pbClaim} return &helper, nil } -func NewStreamClaim(title, description string) (*c.ClaimHelper, error) { +func NewStreamClaim(title, description string) (*c.StakeHelper, error) { streamClaim := new(pb.Claim_Stream) stream := new(pb.Stream) streamClaim.Stream = stream @@ -52,14 +52,14 @@ func NewStreamClaim(title, description string) (*c.ClaimHelper, error) { pbClaim := new(pb.Claim) pbClaim.Type = streamClaim - helper := c.ClaimHelper{Claim: pbClaim} - helper.Title = title - helper.Description = description + helper := c.StakeHelper{Claim: pbClaim} + helper.Claim.Title = title + helper.Claim.Description = description return &helper, nil } -func SignClaim(rawTx *wire.MsgTx, privKey btcec.PrivateKey, claim, channel *c.ClaimHelper, channelClaimID string) error { +func SignClaim(rawTx *wire.MsgTx, privKey btcec.PrivateKey, claim, channel *c.StakeHelper, channelClaimID string) error { claimIDHexBytes, err := hex.DecodeString(channelClaimID) if err != nil { return errors.Err(err) diff --git a/lbrycrd/client.go b/lbrycrd/client.go index a8f9082..9359a77 100644 --- a/lbrycrd/client.go +++ b/lbrycrd/client.go @@ -7,7 +7,7 @@ import ( "strconv" "github.com/lbryio/lbry.go/v2/extras/errors" - c "github.com/lbryio/lbry.go/v2/schema/claim" + c "github.com/lbryio/lbry.go/v2/schema/stake" "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/btcjson" @@ -271,7 +271,7 @@ const ( ClaimSupport ) -func (c *Client) AddStakeToTx(rawTx *wire.MsgTx, claim *c.ClaimHelper, name string, claimAmount float64, scriptType ScriptType) error { +func (c *Client) AddStakeToTx(rawTx *wire.MsgTx, claim *c.StakeHelper, name string, claimAmount float64, scriptType ScriptType) error { address, err := c.GetNewAddress("") if err != nil { @@ -314,7 +314,7 @@ func (c *Client) AddStakeToTx(rawTx *wire.MsgTx, claim *c.ClaimHelper, name stri return nil } -func (c *Client) CreateChannel(name string, amount float64) (*c.ClaimHelper, *btcec.PrivateKey, error) { +func (c *Client) CreateChannel(name string, amount float64) (*c.StakeHelper, *btcec.PrivateKey, error) { channel, key, err := NewChannel() if err != nil { return nil, nil, err diff --git a/schema/claim/serialization.go b/schema/claim/serialization.go deleted file mode 100644 index 64234ae..0000000 --- a/schema/claim/serialization.go +++ /dev/null @@ -1,90 +0,0 @@ -package claim - -import ( - "encoding/hex" - - "github.com/lbryio/lbry.go/v2/extras/errors" - legacy "github.com/lbryio/types/v1/go" - pb "github.com/lbryio/types/v2/go" - - "github.com/golang/protobuf/proto" -) - -func (c *ClaimHelper) serialized() ([]byte, error) { - serialized := c.String() - if serialized == "" { - return nil, errors.Err("not initialized") - } - - if c.LegacyClaim != nil { - return proto.Marshal(c.getLegacyProtobuf()) - } - - return proto.Marshal(c.getProtobuf()) -} - -func (c *ClaimHelper) getProtobuf() *pb.Claim { - claim := &pb.Claim{ - Title: c.GetTitle(), - Description: c.GetDescription(), - Thumbnail: c.GetThumbnail(), - Tags: c.GetTags(), - Languages: c.GetLanguages(), - Locations: c.GetLocations(), - } - if c.GetChannel() != nil { - claim.Type = &pb.Claim_Channel{Channel: c.GetChannel()} - } else if c.GetStream() != nil { - claim.Type = &pb.Claim_Stream{Stream: c.GetStream()} - } else if c.GetCollection() != nil { - claim.Type = &pb.Claim_Collection{Collection: c.GetCollection()} - } else if c.GetRepost() != nil { - claim.Type = &pb.Claim_Repost{Repost: c.GetRepost()} - } - - return claim -} - -func (c *ClaimHelper) getLegacyProtobuf() *legacy.Claim { - v := c.LegacyClaim.GetVersion() - t := c.LegacyClaim.GetClaimType() - return &legacy.Claim{ - Version: &v, - ClaimType: &t, - Stream: c.LegacyClaim.GetStream(), - Certificate: c.LegacyClaim.GetCertificate(), - PublisherSignature: c.LegacyClaim.GetPublisherSignature()} -} - -func (c *ClaimHelper) serializedHexString() (string, error) { - serialized, err := c.serialized() - if err != nil { - return "", err - } - serialized_hex := hex.EncodeToString(serialized) - return serialized_hex, nil -} - -func (c *ClaimHelper) serializedNoSignature() ([]byte, error) { - if c.String() == "" { - return nil, errors.Err("not initialized") - } - if c.Signature == nil { - serialized, err := c.serialized() - if err != nil { - return nil, err - } - return serialized, nil - } else { - if c.LegacyClaim != nil { - clone := &legacy.Claim{} - proto.Merge(clone, c.getLegacyProtobuf()) - proto.ClearAllExtensions(clone.PublisherSignature) - clone.PublisherSignature = nil - return proto.Marshal(clone) - } - clone := &pb.Claim{} - proto.Merge(clone, c.getProtobuf()) - return proto.Marshal(clone) - } -} diff --git a/schema/cli/lbryschema-cli.go b/schema/cli/lbryschema-cli.go index 10e8117..6183559 100644 --- a/schema/cli/lbryschema-cli.go +++ b/schema/cli/lbryschema-cli.go @@ -4,14 +4,14 @@ import ( "fmt" "os" - "github.com/lbryio/lbry.go/v2/schema/claim" + "github.com/lbryio/lbry.go/v2/schema/stake" ) func main() { args := os.Args[1:] if len(args) == 1 { claimBytes := []byte(args[0]) - decoded, err := claim.DecodeClaimBytes(claimBytes, "lbrycrd_main") + decoded, err := stake.DecodeClaimBytes(claimBytes, "lbrycrd_main") if err != nil { fmt.Println("Decoding error:", err) return @@ -25,7 +25,7 @@ func main() { return } else if (len(args) == 2) && (args[1] == "--decode_hex") { claimHex := args[0] - decoded, err := claim.DecodeClaimHex(claimHex, "lbrycrd_main") + decoded, err := stake.DecodeClaimHex(claimHex, "lbrycrd_main") if err != nil { fmt.Println("Decoding error:", err) return diff --git a/schema/claim/keys.go b/schema/keys/keys.go similarity index 79% rename from schema/claim/keys.go rename to schema/keys/keys.go index b34f298..c9cdc67 100644 --- a/schema/claim/keys.go +++ b/schema/keys/keys.go @@ -1,4 +1,4 @@ -package claim +package keys import ( "crypto/elliptic" @@ -10,6 +10,12 @@ import ( "github.com/btcsuite/btcd/btcec" ) +type publicKeyInfo struct { + Raw asn1.RawContent + Algorithm pkix.AlgorithmIdentifier + PublicKey asn1.BitString +} + func PublicKeyToDER(publicKey *btcec.PublicKey) ([]byte, error) { var publicKeyBytes []byte var publicKeyAlgorithm pkix.AlgorithmIdentifier @@ -35,14 +41,7 @@ func PublicKeyToDER(publicKey *btcec.PublicKey) ([]byte, error) { } -func (c *ClaimHelper) GetPublicKey() (*btcec.PublicKey, error) { - if c.GetChannel() == nil { - return nil, errors.Err("claim is not of type channel, so there is no public key to get") - } - return getPublicKeyFromBytes(c.GetChannel().PublicKey) -} - -func getPublicKeyFromBytes(pubKeyBytes []byte) (*btcec.PublicKey, error) { +func GetPublicKeyFromBytes(pubKeyBytes []byte) (*btcec.PublicKey, error) { PKInfo := publicKeyInfo{} asn1.Unmarshal(pubKeyBytes, &PKInfo) pubkeyBytes1 := []byte(PKInfo.PublicKey.Bytes) diff --git a/schema/claim/keys_test.go b/schema/keys/keys_test.go similarity index 58% rename from schema/claim/keys_test.go rename to schema/keys/keys_test.go index 0a5e4f6..c91451c 100644 --- a/schema/claim/keys_test.go +++ b/schema/keys/keys_test.go @@ -1,6 +1,7 @@ -package claim +package keys import ( + "encoding/hex" "testing" "gotest.tools/assert" @@ -10,12 +11,13 @@ import ( // lbry SDK does as this is the bytes that are put into protobuf and the same bytes are used for verify signatures. // Making sure these func TestPublicKeyToDER(t *testing.T) { - cert_claim_hex := "08011002225e0801100322583056301006072a8648ce3d020106052b8104000a03420004d015365a40f3e5c03c87227168e5851f44659837bcf6a3398ae633bc37d04ee19baeb26dc888003bd728146dbea39f5344bf8c52cedaf1a3a1623a0166f4a367" - cert_claim, err := DecodeClaimHex(cert_claim_hex, "lbrycrd_main") + publicKeyHex := "3056301006072a8648ce3d020106052b8104000a03420004d015365a40f3e5c03c87227168e5851f44659837bcf6a3398ae633bc37d04ee19baeb26dc888003bd728146dbea39f5344bf8c52cedaf1a3a1623a0166f4a367" + pubKeyBytes, err := hex.DecodeString(publicKeyHex) if err != nil { t.Error(err) } - p1, err := getPublicKeyFromBytes(cert_claim.Claim.GetChannel().PublicKey) + + p1, err := GetPublicKeyFromBytes(pubKeyBytes) if err != nil { t.Error(err) } @@ -24,11 +26,11 @@ func TestPublicKeyToDER(t *testing.T) { if err != nil { t.Error(err) } - for i, b := range cert_claim.Claim.GetChannel().PublicKey { + for i, b := range pubKeyBytes { assert.Assert(t, b == pubkeyBytes2[i], "DER format in bytes must match!") } - p2, err := getPublicKeyFromBytes(pubkeyBytes2) + p2, err := GetPublicKeyFromBytes(pubkeyBytes2) if err != nil { t.Error(err) } diff --git a/schema/claim/decode_test.go b/schema/stake/decode_test.go similarity index 95% rename from schema/claim/decode_test.go rename to schema/stake/decode_test.go index 101aa82..f85c529 100644 --- a/schema/claim/decode_test.go +++ b/schema/stake/decode_test.go @@ -1,9 +1,11 @@ -package claim +package stake import ( "encoding/hex" "testing" + "github.com/lbryio/lbry.go/v2/schema/keys" + pb "github.com/lbryio/types/v2/go" "github.com/btcsuite/btcd/btcec" @@ -71,20 +73,20 @@ func TestCreateChannelClaim(t *testing.T) { if err != nil { t.Error(err) } - pubKeyBytes, err := PublicKeyToDER(private.PubKey()) + pubKeyBytes, err := keys.PublicKeyToDER(private.PubKey()) if err != nil { t.Error(err) } - claim := &ClaimHelper{Claim: newChannelClaim(), Version: NoSig} - claim.GetChannel().PublicKey = pubKeyBytes - claim.Title = "Test Channel Title" - claim.Description = "Test Channel Description" - claim.GetChannel().Cover = &pb.Source{Url: "http://testcoverurl.com"} - claim.Tags = []string{"TagA", "TagB", "TagC"} - claim.Languages = []*pb.Language{{Language: pb.Language_en}, {Language: pb.Language_es}} - claim.Thumbnail = &pb.Source{Url: "http://thumbnailurl.com"} - claim.GetChannel().WebsiteUrl = "http://homepageurl.com" - claim.Locations = []*pb.Location{{Country: pb.Location_AD}, {Country: pb.Location_US, State: "NJ", City: "some city"}} + claim := &StakeHelper{Claim: newChannelClaim(), Version: NoSig} + claim.Claim.GetChannel().PublicKey = pubKeyBytes + claim.Claim.Title = "Test Channel Title" + claim.Claim.Description = "Test Channel Description" + claim.Claim.GetChannel().Cover = &pb.Source{Url: "http://testcoverurl.com"} + claim.Claim.Tags = []string{"TagA", "TagB", "TagC"} + claim.Claim.Languages = []*pb.Language{{Language: pb.Language_en}, {Language: pb.Language_es}} + claim.Claim.Thumbnail = &pb.Source{Url: "http://thumbnailurl.com"} + claim.Claim.GetChannel().WebsiteUrl = "http://homepageurl.com" + claim.Claim.Locations = []*pb.Location{{Country: pb.Location_AD}, {Country: pb.Location_US, State: "NJ", City: "some city"}} rawClaim, err := claim.CompileValue() if err != nil { diff --git a/schema/claim/migration.go b/schema/stake/migration.go similarity index 99% rename from schema/claim/migration.go rename to schema/stake/migration.go index 2302a4e..2e2cd1b 100644 --- a/schema/claim/migration.go +++ b/schema/stake/migration.go @@ -1,4 +1,4 @@ -package claim +package stake import ( "encoding/hex" diff --git a/schema/claim/migration_test.go b/schema/stake/migration_test.go similarity index 96% rename from schema/claim/migration_test.go rename to schema/stake/migration_test.go index cf5cc29..4fb4ca3 100644 --- a/schema/claim/migration_test.go +++ b/schema/stake/migration_test.go @@ -1,4 +1,4 @@ -package claim +package stake import ( "bytes" @@ -232,13 +232,13 @@ func TestMigrationFromV1YTSync(t *testing.T) { if err != nil { t.Error(err) } - assert.Assert(t, claim.GetTitle() == "Here are 5 Reasons I ❤️ Nextcloud | TLG") - assert.Assert(t, claim.GetDescription() == "Find out more about Nextcloud: https://nextcloud.com/\n\nYou can find me on these socials:\n * Forums: https://forum.heavyelement.io/\n * Podcast: https://offtopical.net\n * Patreon: https://patreon.com/thelinuxgamer\n * Merch: https://teespring.com/stores/official-linux-gamer\n * Twitch: https://twitch.tv/xondak\n * Twitter: https://twitter.com/thelinuxgamer\n\n...\nhttps://www.youtube.com/watch?v=FrTdBCOS_fc") + assert.Assert(t, claim.Claim.GetTitle() == "Here are 5 Reasons I ❤️ Nextcloud | TLG") + assert.Assert(t, claim.Claim.GetDescription() == "Find out more about Nextcloud: https://nextcloud.com/\n\nYou can find me on these socials:\n * Forums: https://forum.heavyelement.io/\n * Podcast: https://offtopical.net\n * Patreon: https://patreon.com/thelinuxgamer\n * Merch: https://teespring.com/stores/official-linux-gamer\n * Twitch: https://twitch.tv/xondak\n * Twitter: https://twitter.com/thelinuxgamer\n\n...\nhttps://www.youtube.com/watch?v=FrTdBCOS_fc") assert.Assert(t, claim.GetStream().GetLicense() == "Copyrighted (contact author)") assert.Assert(t, claim.GetStream().GetAuthor() == "The Linux Gamer") //?assert.Assert(t, claim.GetStream().GetLanguages()[0]) assert.Assert(t, claim.GetStream().GetSource().GetMediaType() == "video/mp4") - assert.Assert(t, claim.GetThumbnail().GetUrl() == "https://berk.ninja/thumbnails/FrTdBCOS_fc") + assert.Assert(t, claim.Claim.GetThumbnail().GetUrl() == "https://berk.ninja/thumbnails/FrTdBCOS_fc") sdHashBytes, err := hex.DecodeString("040e8ac6e89c061f982528c23ad33829fd7146435bf7a4cc22f0bff70c4fe0b91fd36da9a375e3e1c171db825bf5d1f3") if err != nil { t.Error(err) @@ -254,7 +254,7 @@ func TestMigrationFromV1YTSync(t *testing.T) { if err != nil { t.Error(err) } - assert.Assert(t, bytes.Equal(pubKeyBytes, channel.GetChannel().GetPublicKey())) + assert.Assert(t, bytes.Equal(pubKeyBytes, channel.Claim.GetChannel().GetPublicKey())) } func TestMigrationFromV1UnsignedWithFee(t *testing.T) { @@ -263,8 +263,8 @@ func TestMigrationFromV1UnsignedWithFee(t *testing.T) { if err != nil { t.Error(err) } - assert.Assert(t, claim.GetTitle() == "rpg midi") - assert.Assert(t, claim.GetDescription() == "midi") + assert.Assert(t, claim.Claim.GetTitle() == "rpg midi") + assert.Assert(t, claim.Claim.GetDescription() == "midi") assert.Assert(t, claim.GetStream().GetLicense() == "Creative Commons Attribution 4.0 International") assert.Assert(t, claim.GetStream().GetAuthor() == "rpg midi") //assert.Assert(t, claim.GetStream().GetLanguage() == "en") diff --git a/schema/claim/pretty.go b/schema/stake/pretty.go similarity index 65% rename from schema/claim/pretty.go rename to schema/stake/pretty.go index a2d4155..f5fdbf4 100644 --- a/schema/claim/pretty.go +++ b/schema/stake/pretty.go @@ -1,17 +1,21 @@ -package claim +package stake import ( "encoding/json" "fmt" + "github.com/golang/protobuf/jsonpb" ) -func marshalToString(c *ClaimHelper) (string, error) { +func marshalToString(c *StakeHelper) (string, error) { m_pb := &jsonpb.Marshaler{} - return m_pb.MarshalToString(c) + if c.IsSupport() { + return m_pb.MarshalToString(c.Support) + } + return m_pb.MarshalToString(c.Claim) } -func (c *ClaimHelper) RenderJSON() (string, error) { +func (c *StakeHelper) RenderJSON() (string, error) { r, err := marshalToString(c) if err != nil { fmt.Println("err") diff --git a/schema/claim/schema.go b/schema/stake/schema.go similarity index 99% rename from schema/claim/schema.go rename to schema/stake/schema.go index 3ab7b43..8d8f30d 100644 --- a/schema/claim/schema.go +++ b/schema/stake/schema.go @@ -1,4 +1,4 @@ -package claim +package stake import ( "encoding/json" diff --git a/schema/stake/serialization.go b/schema/stake/serialization.go new file mode 100644 index 0000000..d066781 --- /dev/null +++ b/schema/stake/serialization.go @@ -0,0 +1,105 @@ +package stake + +import ( + "encoding/hex" + + "github.com/lbryio/lbry.go/v2/extras/errors" + legacy "github.com/lbryio/types/v1/go" + pb "github.com/lbryio/types/v2/go" + + "github.com/golang/protobuf/proto" +) + +func (c *StakeHelper) serialized() ([]byte, error) { + serialized := c.Claim.String() + c.Support.String() + if serialized == "" { + return nil, errors.Err("not initialized") + } + + if c.LegacyClaim != nil { + return proto.Marshal(c.getLegacyProtobuf()) + } else if c.IsSupport() { + return proto.Marshal(c.getSupportProtobuf()) + } + + return proto.Marshal(c.getClaimProtobuf()) +} + +func (c *StakeHelper) getClaimProtobuf() *pb.Claim { + claim := &pb.Claim{ + Title: c.Claim.GetTitle(), + Description: c.Claim.GetDescription(), + Thumbnail: c.Claim.GetThumbnail(), + Tags: c.Claim.GetTags(), + Languages: c.Claim.GetLanguages(), + Locations: c.Claim.GetLocations(), + } + if c.Claim.GetChannel() != nil { + claim.Type = &pb.Claim_Channel{Channel: c.Claim.GetChannel()} + } else if c.GetStream() != nil { + claim.Type = &pb.Claim_Stream{Stream: c.GetStream()} + } else if c.Claim.GetCollection() != nil { + claim.Type = &pb.Claim_Collection{Collection: c.Claim.GetCollection()} + } else if c.Claim.GetRepost() != nil { + claim.Type = &pb.Claim_Repost{Repost: c.Claim.GetRepost()} + } + + return claim +} + +func (c *StakeHelper) getSupportProtobuf() *pb.Support { + return &pb.Support{ + Emoji: c.Support.GetEmoji(), + XXX_NoUnkeyedLiteral: struct{}{}, + XXX_unrecognized: nil, + XXX_sizecache: 0, + } +} + +func (c *StakeHelper) getLegacyProtobuf() *legacy.Claim { + v := c.LegacyClaim.GetVersion() + t := c.LegacyClaim.GetClaimType() + return &legacy.Claim{ + Version: &v, + ClaimType: &t, + Stream: c.LegacyClaim.GetStream(), + Certificate: c.LegacyClaim.GetCertificate(), + PublisherSignature: c.LegacyClaim.GetPublisherSignature()} +} + +func (c *StakeHelper) serializedHexString() (string, error) { + serialized, err := c.serialized() + if err != nil { + return "", err + } + serialized_hex := hex.EncodeToString(serialized) + return serialized_hex, nil +} + +func (c *StakeHelper) serializedNoSignature() ([]byte, error) { + if c.Claim.String() == "" && c.Support.String() == "" { + return nil, errors.Err("not initialized") + } + if c.Signature == nil { + serialized, err := c.serialized() + if err != nil { + return nil, err + } + return serialized, nil + } else { + if c.LegacyClaim != nil { + clone := &legacy.Claim{} + proto.Merge(clone, c.getLegacyProtobuf()) + proto.ClearAllExtensions(clone.PublisherSignature) + clone.PublisherSignature = nil + return proto.Marshal(clone) + } else if c.IsSupport() { + clone := &pb.Support{} + proto.Merge(clone, c.getSupportProtobuf()) + return proto.Marshal(clone) + } + clone := &pb.Claim{} + proto.Merge(clone, c.getClaimProtobuf()) + return proto.Marshal(clone) + } +} diff --git a/schema/claim/sign.go b/schema/stake/sign.go similarity index 84% rename from schema/claim/sign.go rename to schema/stake/sign.go index a660fec..dcf97d1 100644 --- a/schema/claim/sign.go +++ b/schema/stake/sign.go @@ -1,4 +1,4 @@ -package claim +package stake import ( "crypto/sha256" @@ -10,8 +10,8 @@ import ( "github.com/btcsuite/btcd/btcec" ) -func Sign(privKey btcec.PrivateKey, channel ClaimHelper, claim ClaimHelper, k string) (*Signature, error) { - if channel.GetChannel() == nil { +func Sign(privKey btcec.PrivateKey, channel StakeHelper, claim StakeHelper, k string) (*Signature, error) { + if channel.Claim.GetChannel() == nil { return nil, errors.Err("claim as channel is not of type channel") } if claim.LegacyClaim != nil { @@ -21,7 +21,7 @@ func Sign(privKey btcec.PrivateKey, channel ClaimHelper, claim ClaimHelper, k st return claim.sign(privKey, channel, k) } -func (c *ClaimHelper) sign(privKey btcec.PrivateKey, channel ClaimHelper, firstInputTxID string) (*Signature, error) { +func (c *StakeHelper) sign(privKey btcec.PrivateKey, channel StakeHelper, firstInputTxID string) (*Signature, error) { txidBytes, err := hex.DecodeString(firstInputTxID) if err != nil { @@ -52,7 +52,7 @@ func (c *ClaimHelper) sign(privKey btcec.PrivateKey, channel ClaimHelper, firstI } -func (c *ClaimHelper) signV1(privKey btcec.PrivateKey, channel ClaimHelper, claimAddress string) (*Signature, error) { +func (c *StakeHelper) signV1(privKey btcec.PrivateKey, channel StakeHelper, claimAddress string) (*Signature, error) { metadataBytes, err := c.serializedNoSignature() if err != nil { return nil, errors.Err(err) diff --git a/schema/claim/sign_test.go b/schema/stake/sign_test.go similarity index 56% rename from schema/claim/sign_test.go rename to schema/stake/sign_test.go index e813f07..e2e4752 100644 --- a/schema/claim/sign_test.go +++ b/schema/stake/sign_test.go @@ -1,9 +1,13 @@ -package claim +package stake import ( "encoding/hex" "testing" + pb "github.com/lbryio/types/v2/go" + + "github.com/lbryio/lbry.go/v2/schema/keys" + "github.com/btcsuite/btcd/btcec" "gotest.tools/assert" ) @@ -14,13 +18,13 @@ func TestSign(t *testing.T) { t.Error(err) return } - channel := &ClaimHelper{newChannelClaim(), nil, nil, NoSig, nil, nil} - pubkeyBytes, err := PublicKeyToDER(privateKey.PubKey()) + channel := &StakeHelper{newChannelClaim(), nil, nil, nil, NoSig, nil, nil} + pubkeyBytes, err := keys.PublicKeyToDER(privateKey.PubKey()) if err != nil { t.Error(err) return } - channel.GetChannel().PublicKey = pubkeyBytes + channel.Claim.GetChannel().PublicKey = pubkeyBytes claimID := "cf3f7c898af87cc69b06a6ac7899efb9a4878fdb" //Fake txid := "4c1df9e022e396859175f9bfa69b38e444db10fb53355fa99a0989a83bcdb82f" //Fake claimIDHexBytes, err := hex.DecodeString(claimID) @@ -29,7 +33,7 @@ func TestSign(t *testing.T) { return } - claim := &ClaimHelper{newStreamClaim(), nil, reverseBytes(claimIDHexBytes), WithSig, nil, nil} + claim := &StakeHelper{newStreamClaim(), nil, nil, reverseBytes(claimIDHexBytes), WithSig, nil, nil} claim.Claim.Title = "Test title" claim.Claim.Description = "Test description" sig, err := Sign(*privateKey, *channel, *claim, txid) @@ -78,6 +82,61 @@ func TestSign(t *testing.T) { } +func TestSignSupportWithChannel(t *testing.T) { + cert_claim_hex := "08011002225e0801100322583056301006072a8648ce3d020106052b8104000a03420004d015365a40f3e5c03c87227168e5851f44659837bcf6a3398ae633bc37d04ee19baeb26dc888003bd728146dbea39f5344bf8c52cedaf1a3a1623a0166f4a367" + channel, err := DecodeClaimHex(cert_claim_hex, "lbrycrd_main") + if err != nil { + t.Error(err) + } + privateKey, err := btcec.NewPrivateKey(btcec.S256()) + if err != nil { + t.Error(err) + return + } + pubkeyBytes, err := keys.PublicKeyToDER(privateKey.PubKey()) + if err != nil { + t.Error(err) + return + } + channel.Claim.GetChannel().PublicKey = pubkeyBytes + + claimID := "251305ca93d4dbedb50dceb282ebcb7b07b7ac64" + txid := "4c1df9e022e396859175f9bfa69b38e444db10fb53355fa99a0989a83bcdb82f" //Fake + claimIDHexBytes, err := hex.DecodeString(claimID) + if err != nil { + t.Error(err) + return + } + + support := &StakeHelper{nil, &pb.Support{}, nil, reverseBytes(claimIDHexBytes), WithSig, nil, nil} + sig, err := Sign(*privateKey, *channel, *support, txid) + if err != nil { + t.Error(err) + return + } + + signatureBytes, err := sig.LBRYSDKEncode() + if err != nil { + t.Error(err) + return + } + + support.Signature = signatureBytes + compiledSupport, err := support.CompileValue() + if err != nil { + t.Error(err) + } + support, err = DecodeSupportBytes(compiledSupport, "lbrycrd_main") + + valid, err := support.ValidateClaimSignature(channel, txid, claimID, "lbrycrd_main") + if err != nil { + t.Error(err) + return + } + + assert.Assert(t, valid, "could not verify signature") +} + func TestSignWithV1Channel(t *testing.T) { cert_claim_hex := "08011002225e0801100322583056301006072a8648ce3d020106052b8104000a03420004d015365a40f3e5c03c87227168e5851f44659837bcf6a3398ae633bc37d04ee19baeb26dc888003bd728146dbea39f5344bf8c52cedaf1a3a1623a0166f4a367" channel, err := DecodeClaimHex(cert_claim_hex, "lbrycrd_main") @@ -89,12 +148,12 @@ func TestSignWithV1Channel(t *testing.T) { t.Error(err) return } - pubkeyBytes, err := PublicKeyToDER(privateKey.PubKey()) + pubkeyBytes, err := keys.PublicKeyToDER(privateKey.PubKey()) if err != nil { t.Error(err) return } - channel.GetChannel().PublicKey = pubkeyBytes + channel.Claim.GetChannel().PublicKey = pubkeyBytes claimID := "251305ca93d4dbedb50dceb282ebcb7b07b7ac64" txid := "4c1df9e022e396859175f9bfa69b38e444db10fb53355fa99a0989a83bcdb82f" //Fake @@ -104,7 +163,7 @@ func TestSignWithV1Channel(t *testing.T) { return } - claim := &ClaimHelper{newStreamClaim(), nil, reverseBytes(claimIDHexBytes), WithSig, nil, nil} + claim := &StakeHelper{newStreamClaim(), nil, nil, reverseBytes(claimIDHexBytes), WithSig, nil, nil} claim.Claim.Title = "Test title" claim.Claim.Description = "Test description" sig, err := Sign(*privateKey, *channel, *claim, txid) diff --git a/schema/claim/claim.go b/schema/stake/stake.go similarity index 65% rename from schema/claim/claim.go rename to schema/stake/stake.go index f42fe95..0aac6cc 100644 --- a/schema/claim/claim.go +++ b/schema/stake/stake.go @@ -1,4 +1,4 @@ -package claim +package stake import ( "encoding/hex" @@ -6,9 +6,11 @@ import ( "github.com/lbryio/lbry.go/v2/extras/errors" "github.com/lbryio/lbry.go/v2/schema/address" + "github.com/lbryio/lbry.go/v2/schema/keys" legacy_pb "github.com/lbryio/types/v1/go" pb "github.com/lbryio/types/v2/go" + "github.com/btcsuite/btcd/btcec" "github.com/golang/protobuf/proto" ) @@ -25,8 +27,9 @@ const ( UNKNOWN = version(byte(2)) ) -type ClaimHelper struct { - *pb.Claim +type StakeHelper struct { + Claim *pb.Claim + Support *pb.Support LegacyClaim *legacy_pb.Claim ClaimID []byte Version version @@ -36,7 +39,7 @@ type ClaimHelper struct { const migrationErrorMessage = "migration from v1 to v2 protobuf failed with: " -func (c *ClaimHelper) ValidateAddresses(blockchainName string) error { +func (c *StakeHelper) ValidateAddresses(blockchainName string) error { if c.Claim != nil { // V2 // check the validity of a fee address if c.Claim.GetStream() != nil { @@ -46,7 +49,7 @@ func (c *ClaimHelper) ValidateAddresses(blockchainName string) error { } else { return nil } - } else if c.GetChannel() != nil { + } else if c.Claim.GetChannel() != nil { return nil } } @@ -80,8 +83,8 @@ func getVersionFromByte(versionByte byte) version { return UNKNOWN } -func (c *ClaimHelper) ValidateCertificate() error { - if c.GetChannel() == nil { +func (c *StakeHelper) ValidateCertificate() error { + if !c.IsClaim() || c.Claim.GetChannel() == nil { return nil } _, err := c.GetPublicKey() @@ -91,8 +94,24 @@ func (c *ClaimHelper) ValidateCertificate() error { return nil } -func (c *ClaimHelper) LoadFromBytes(raw_claim []byte, blockchainName string) error { - if c.String() != "" { +func (c *StakeHelper) IsClaim() bool { + return c.Claim != nil && c.Claim.String() != "" +} + +func (c *StakeHelper) IsSupport() bool { + return c.Support != nil +} + +func (c *StakeHelper) LoadFromBytes(raw_claim []byte, blockchainName string) error { + return c.loadFromBytes(raw_claim, false, blockchainName) +} + +func (c *StakeHelper) LoadSupportFromBytes(raw_claim []byte, blockchainName string) error { + return c.loadFromBytes(raw_claim, true, blockchainName) +} + +func (c *StakeHelper) loadFromBytes(raw_claim []byte, isSupport bool, blockchainName string) error { + if c.Claim.String() != "" && !isSupport { return errors.Err("already initialized") } if len(raw_claim) < 1 { @@ -101,13 +120,14 @@ func (c *ClaimHelper) LoadFromBytes(raw_claim []byte, blockchainName string) err var claim_pb *pb.Claim var legacy_claim_pb *legacy_pb.Claim + var support_pb *pb.Support version := getVersionFromByte(raw_claim[0]) //First byte = version pbPayload := raw_claim[1:] var claimID []byte var signature []byte if version == WithSig { - if len(raw_claim) < 86 { + if len(raw_claim) < 85 { return errors.Err("signature version indicated by 1st byte but not enough bytes for valid format") } claimID = raw_claim[1:21] // channel claimid = next 20 bytes @@ -115,8 +135,17 @@ func (c *ClaimHelper) LoadFromBytes(raw_claim []byte, blockchainName string) err pbPayload = raw_claim[85:] // protobuf payload = remaining bytes } - claim_pb = &pb.Claim{} - err := proto.Unmarshal(pbPayload, claim_pb) + var err error + if !isSupport { + claim_pb = &pb.Claim{} + err = proto.Unmarshal(pbPayload, claim_pb) + } else { + support := &pb.Support{} + err = proto.Unmarshal(pbPayload, support) + if err == nil { + support_pb = support + } + } if err != nil { legacy_claim_pb = &legacy_pb.Claim{} legacyErr := proto.Unmarshal(raw_claim, legacy_claim_pb) @@ -138,8 +167,9 @@ func (c *ClaimHelper) LoadFromBytes(raw_claim []byte, blockchainName string) err } } - *c = ClaimHelper{ + *c = StakeHelper{ Claim: claim_pb, + Support: support_pb, LegacyClaim: legacy_claim_pb, ClaimID: claimID, Version: version, @@ -161,7 +191,7 @@ func (c *ClaimHelper) LoadFromBytes(raw_claim []byte, blockchainName string) err return nil } -func (c *ClaimHelper) LoadFromHexString(claim_hex string, blockchainName string) error { +func (c *StakeHelper) LoadFromHexString(claim_hex string, blockchainName string) error { buf, err := hex.DecodeString(claim_hex) if err != nil { return err @@ -169,8 +199,16 @@ func (c *ClaimHelper) LoadFromHexString(claim_hex string, blockchainName string) return c.LoadFromBytes(buf, blockchainName) } -func DecodeClaimProtoBytes(serialized []byte, blockchainName string) (*ClaimHelper, error) { - claim := &ClaimHelper{&pb.Claim{}, nil, nil, NoSig, nil, nil} +func (c *StakeHelper) LoadSupportFromHexString(claim_hex string, blockchainName string) error { + buf, err := hex.DecodeString(claim_hex) + if err != nil { + return err + } + return c.LoadSupportFromBytes(buf, blockchainName) +} + +func DecodeClaimProtoBytes(serialized []byte, blockchainName string) (*StakeHelper, error) { + claim := &StakeHelper{&pb.Claim{}, &pb.Support{}, nil, nil, NoSig, nil, nil} err := claim.LoadFromBytes(serialized, blockchainName) if err != nil { return nil, err @@ -178,7 +216,16 @@ func DecodeClaimProtoBytes(serialized []byte, blockchainName string) (*ClaimHelp return claim, nil } -func DecodeClaimHex(serialized string, blockchainName string) (*ClaimHelper, error) { +func DecodeSupportProtoBytes(serialized []byte, blockchainName string) (*StakeHelper, error) { + claim := &StakeHelper{nil, &pb.Support{}, nil, nil, NoSig, nil, nil} + err := claim.LoadSupportFromBytes(serialized, blockchainName) + if err != nil { + return nil, err + } + return claim, nil +} + +func DecodeClaimHex(serialized string, blockchainName string) (*StakeHelper, error) { claim_bytes, err := hex.DecodeString(serialized) if err != nil { return nil, errors.Err(err) @@ -187,12 +234,12 @@ func DecodeClaimHex(serialized string, blockchainName string) (*ClaimHelper, err } // DecodeClaimBytes take a byte array and tries to decode it to a protobuf claim or migrate it from either json v1,2,3 or pb v1 -func DecodeClaimBytes(serialized []byte, blockchainName string) (*ClaimHelper, error) { +func DecodeClaimBytes(serialized []byte, blockchainName string) (*StakeHelper, error) { helper, err := DecodeClaimProtoBytes(serialized, blockchainName) if err == nil { return helper, nil } - helper = &ClaimHelper{} + helper = &StakeHelper{} //If protobuf fails, try json versions before returning an error. v1Claim := new(V1Claim) err = v1Claim.Unmarshal(serialized) @@ -225,14 +272,23 @@ func DecodeClaimBytes(serialized []byte, blockchainName string) (*ClaimHelper, e return helper, nil } -func (c *ClaimHelper) GetStream() *pb.Stream { +// DecodeSupportBytes take a byte array and tries to decode it to a protobuf support +func DecodeSupportBytes(serialized []byte, blockchainName string) (*StakeHelper, error) { + helper, err := DecodeSupportProtoBytes(serialized, blockchainName) + if err != nil { + return nil, errors.Err(err) + } + return helper, nil +} + +func (c *StakeHelper) GetStream() *pb.Stream { if c != nil { return c.Claim.GetStream() } return nil } -func (c *ClaimHelper) CompileValue() ([]byte, error) { +func (c *StakeHelper) CompileValue() ([]byte, error) { payload, err := c.serialized() if err != nil { return nil, err @@ -247,3 +303,15 @@ func (c *ClaimHelper) CompileValue() ([]byte, error) { return value, nil } + +func (c *StakeHelper) GetPublicKey() (*btcec.PublicKey, error) { + if c.IsClaim() { + if c.Claim.GetChannel() == nil { + return nil, errors.Err("claim is not of type channel, so there is no public key to get") + } + + } else if c.IsSupport() { + return nil, errors.Err("stake is a support and does not come with a public key to get") + } + return keys.GetPublicKeyFromBytes(c.Claim.GetChannel().PublicKey) +} diff --git a/schema/claim/claim_test.go b/schema/stake/stake_test.go similarity index 97% rename from schema/claim/claim_test.go rename to schema/stake/stake_test.go index 493a5df..dfb6a49 100644 --- a/schema/claim/claim_test.go +++ b/schema/stake/stake_test.go @@ -1,4 +1,4 @@ -package claim +package stake import "testing" diff --git a/schema/claim/validator.go b/schema/stake/validator.go similarity index 86% rename from schema/claim/validator.go rename to schema/stake/validator.go index 77ed698..6704d8d 100644 --- a/schema/claim/validator.go +++ b/schema/stake/validator.go @@ -1,10 +1,8 @@ -package claim +package stake import ( "crypto/ecdsa" "crypto/sha256" - "crypto/x509/pkix" - "encoding/asn1" "encoding/binary" "encoding/hex" "math/big" @@ -13,12 +11,6 @@ import ( "github.com/lbryio/lbry.go/v2/schema/address" ) -type publicKeyInfo struct { - Raw asn1.RawContent - Algorithm pkix.AlgorithmIdentifier - PublicKey asn1.BitString -} - const SECP256k1 = "SECP256k1" //const NIST256p = "NIST256p" @@ -34,7 +26,7 @@ func getClaimSignatureDigest(bytes ...[]byte) [32]byte { return [32]byte(digest) } -func (c *ClaimHelper) VerifyDigest(certificate *ClaimHelper, signature [64]byte, digest [32]byte) bool { +func (c *StakeHelper) VerifyDigest(certificate *StakeHelper, signature [64]byte, digest [32]byte) bool { if certificate == nil { return false } @@ -50,7 +42,7 @@ func (c *ClaimHelper) VerifyDigest(certificate *ClaimHelper, signature [64]byte, return ecdsa.Verify(pk.ToECDSA(), digest[:], R, S) } -func (c *ClaimHelper) ValidateClaimSignature(certificate *ClaimHelper, k string, certificateId string, blockchainName string) (bool, error) { +func (c *StakeHelper) ValidateClaimSignature(certificate *StakeHelper, k string, certificateId string, blockchainName string) (bool, error) { if c.LegacyClaim != nil { return c.validateV1ClaimSignature(certificate, k, certificateId, blockchainName) } @@ -58,7 +50,7 @@ func (c *ClaimHelper) ValidateClaimSignature(certificate *ClaimHelper, k string, return c.validateClaimSignature(certificate, k, certificateId, blockchainName) } -func (c *ClaimHelper) validateClaimSignature(certificate *ClaimHelper, firstInputTxHash, certificateId string, blockchainName string) (bool, error) { +func (c *StakeHelper) validateClaimSignature(certificate *StakeHelper, firstInputTxHash, certificateId string, blockchainName string) (bool, error) { certificateIdSlice, err := hex.DecodeString(certificateId) if err != nil { return false, errors.Err(err) @@ -82,7 +74,7 @@ func (c *ClaimHelper) validateClaimSignature(certificate *ClaimHelper, firstInpu return c.VerifyDigest(certificate, signatureBytes, claimDigest), nil } -func (c *ClaimHelper) validateV1ClaimSignature(certificate *ClaimHelper, claimAddy string, certificateId string, blockchainName string) (bool, error) { +func (c *StakeHelper) validateV1ClaimSignature(certificate *StakeHelper, claimAddy string, certificateId string, blockchainName string) (bool, error) { addressBytes, err := address.DecodeAddress(claimAddy, blockchainName) if err != nil { return false, err diff --git a/schema/claim/validator_test.go b/schema/stake/validator_test.go similarity index 99% rename from schema/claim/validator_test.go rename to schema/stake/validator_test.go index ef88a4d..23df990 100644 --- a/schema/claim/validator_test.go +++ b/schema/stake/validator_test.go @@ -1,4 +1,4 @@ -package claim +package stake import ( "testing"