Merge pull request #84 from lbryio/stake_supports

Rename packages to represent stakes (claims || supports)
This commit is contained in:
Mark 2020-11-18 15:36:19 -05:00 committed by GitHub
commit e9753ffdc7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 370 additions and 207 deletions

View file

@ -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"

2
go.mod
View file

@ -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

3
go.sum
View file

@ -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=

View file

@ -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
}

View file

@ -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)

View file

@ -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

View file

@ -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)
}
}

View file

@ -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

View file

@ -1,15 +1,30 @@
package claim
package keys
import (
"crypto/elliptic"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/pem"
"github.com/lbryio/lbry.go/v2/extras/errors"
"github.com/btcsuite/btcd/btcec"
)
type publicKeyInfo struct {
Raw asn1.RawContent
Algorithm pkix.AlgorithmIdentifier
PublicKey asn1.BitString
}
//This type provides compatibility with the btcec package
type ecPrivateKey struct {
Version int
PrivateKey []byte
NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"`
PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"`
}
func PublicKeyToDER(publicKey *btcec.PublicKey) ([]byte, error) {
var publicKeyBytes []byte
var publicKeyAlgorithm pkix.AlgorithmIdentifier
@ -35,16 +50,18 @@ 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)
return btcec.ParsePubKey(pubkeyBytes1, btcec.S256())
}
//Returns a btec.Private key object if provided a correct secp256k1 encoded pem.
func ExtractKeyFromPem(pm string) (*btcec.PrivateKey, *btcec.PublicKey) {
byta := []byte(pm)
blck, _ := pem.Decode(byta)
var ecp ecPrivateKey
asn1.Unmarshal(blck.Bytes, &ecp)
return btcec.PrivKeyFromBytes(btcec.S256(), ecp.PrivateKey)
}

View file

@ -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)
}

View file

@ -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 {

View file

@ -1,4 +1,4 @@
package claim
package stake
import (
"encoding/hex"

View file

@ -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")

View file

@ -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")

View file

@ -1,4 +1,4 @@
package claim
package stake
import (
"encoding/json"

View file

@ -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)
}
}

View file

@ -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)

View file

@ -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)

View file

@ -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)
}

View file

@ -1,4 +1,4 @@
package claim
package stake
import "testing"

View file

@ -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

View file

@ -1,4 +1,4 @@
package claim
package stake
import (
"testing"