diff --git a/embed_test.go b/embed_test.go index 77b821f0..eda72b43 100644 --- a/embed_test.go +++ b/embed_test.go @@ -95,7 +95,11 @@ func TestEncodeDemo(t *testing.T) { }{ {PubName{Foo{"pub-foo"}}, &PubName{}, "Foo: pub-foo"}, {PubName{Bar{7}}, &PubName{}, "Bar #7"}, + // Note these fail - if you can figure a solution here, I'll buy you a beer :) + // (ebuchman is right, you must either break the reflection system, or modify go-wire) + // but such a mod would let us make REALLY sure that no one could construct like this + // {PrivName{Foo{"priv-foo"}}, &PrivName{}, "Foo: priv-foo"}, // {PrivName{Bar{9}}, &PrivName{}, "Bar #9"}, } diff --git a/encode_test.go b/encode_test.go index 71b7b3ae..9a8e5902 100644 --- a/encode_test.go +++ b/encode_test.go @@ -82,25 +82,21 @@ func TestKeyEncodings(t *testing.T) { for _, tc := range cases { // check (de/en)codings of private key - priv2 := PrivKey{} + var priv2, priv3, priv4 PrivKey checkWire(t, tc.privKey, &priv2, tc.keyType) assert.EqualValues(t, tc.privKey, priv2) - priv3 := PrivKey{} checkJSON(t, tc.privKey, &priv3, tc.keyName) assert.EqualValues(t, tc.privKey, priv3) - priv4 := PrivKey{} checkWireJSON(t, tc.privKey, &priv4, tc.keyType) assert.EqualValues(t, tc.privKey, priv4) // check (de/en)codings of public key pubKey := tc.privKey.PubKey() - pub2 := PubKey{} + var pub2, pub3, pub4 PubKey checkWire(t, pubKey, &pub2, tc.keyType) assert.EqualValues(t, pubKey, pub2) - pub3 := PubKey{} checkJSON(t, pubKey, &pub3, tc.keyName) assert.EqualValues(t, pubKey, pub3) - pub4 := PubKey{} checkWireJSON(t, pubKey, &pub4, tc.keyType) assert.EqualValues(t, pubKey, pub4) } @@ -115,17 +111,17 @@ func toFromJSON(t *testing.T, in interface{}, recvr interface{}) { func TestNilEncodings(t *testing.T) { // make sure sigs are okay with nil - a, b := Signature{}, Signature{} + var a, b Signature toFromJSON(t, a, &b) assert.EqualValues(t, a, b) // make sure sigs are okay with nil - c, d := PubKey{}, PubKey{} + var c, d PubKey toFromJSON(t, c, &d) assert.EqualValues(t, c, d) // make sure sigs are okay with nil - e, f := PrivKey{}, PrivKey{} + var e, f PrivKey toFromJSON(t, e, &f) assert.EqualValues(t, e, f) diff --git a/priv_key.go b/priv_key.go index 5aa2d05a..d21bdf45 100644 --- a/priv_key.go +++ b/priv_key.go @@ -11,7 +11,14 @@ import ( "github.com/tendermint/go-wire" ) -// PrivKeyInner is now the interface itself, use PrivKey in all code +/* +DO NOT USE this interface. + +It is public by necessity but should never be used directly +outside of this package. + +Only use the PrivKey, never the PrivKeyInner +*/ type PrivKeyInner interface { Bytes() []byte Sign(msg []byte) Signature @@ -36,11 +43,13 @@ func init() { RegisterImplementation(PrivKeySecp256k1{}, NameSecp256k1, TypeSecp256k1) } -// PrivKey handles all encoding and exposes methods +// PrivKey should be used instead of an interface in all external packages +// unless you demand a concrete implementation, then use that directly. type PrivKey struct { PrivKeyInner `json:"unwrap"` } +// WrapPrivKey goes from concrete implementation to "interface" struct func WrapPrivKey(pk PrivKeyInner) PrivKey { if wrap, ok := pk.(PrivKey); ok { pk = wrap.Unwrap() @@ -48,6 +57,7 @@ func WrapPrivKey(pk PrivKeyInner) PrivKey { return PrivKey{pk} } +// Unwrap recovers the concrete interface safely (regardless of levels of embeds) func (p PrivKey) Unwrap() PrivKeyInner { pk := p.PrivKeyInner for wrap, ok := pk.(PrivKey); ok; wrap, ok = pk.(PrivKey) { diff --git a/pub_key.go b/pub_key.go index 8373eb34..a763688f 100644 --- a/pub_key.go +++ b/pub_key.go @@ -13,7 +13,14 @@ import ( "golang.org/x/crypto/ripemd160" ) -// PubKeyInner is now the interface itself, use PubKey struct in all code +/* +DO NOT USE this interface. + +It is public by necessity but should never be used directly +outside of this package. + +Only use the PubKey, never the PubKeyInner +*/ type PubKeyInner interface { Address() []byte Bytes() []byte @@ -31,11 +38,13 @@ func init() { RegisterImplementation(PubKeySecp256k1{}, NameSecp256k1, TypeSecp256k1) } -// PubKey add json serialization to PubKeyInner +// PubKey should be used instead of an interface in all external packages +// unless you demand a concrete implementation, then use that directly. type PubKey struct { PubKeyInner `json:"unwrap"` } +// WrapPubKey goes from concrete implementation to "interface" struct func WrapPubKey(pk PubKeyInner) PubKey { if wrap, ok := pk.(PubKey); ok { pk = wrap.Unwrap() @@ -43,6 +52,7 @@ func WrapPubKey(pk PubKeyInner) PubKey { return PubKey{pk} } +// Unwrap recovers the concrete interface safely (regardless of levels of embeds) func (p PubKey) Unwrap() PubKeyInner { pk := p.PubKeyInner for wrap, ok := pk.(PubKey); ok; wrap, ok = pk.(PubKey) { diff --git a/signature.go b/signature.go index ba40166c..bb3e8f11 100644 --- a/signature.go +++ b/signature.go @@ -9,8 +9,14 @@ import ( "github.com/tendermint/go-wire" ) -// SignatureInner is now the interface itself. -// Use Signature in all code +/* +DO NOT USE this interface. + +It is public by necessity but should never be used directly +outside of this package. + +Only use the Signature, never the SignatureInner +*/ type SignatureInner interface { Bytes() []byte IsZero() bool @@ -27,11 +33,13 @@ func init() { RegisterImplementation(SignatureSecp256k1{}, NameSecp256k1, TypeSecp256k1) } -// Signature add json serialization to Signature +// Signature should be used instead of an interface in all external packages +// unless you demand a concrete implementation, then use that directly. type Signature struct { SignatureInner `json:"unwrap"` } +// WrapSignature goes from concrete implementation to "interface" struct func WrapSignature(pk SignatureInner) Signature { if wrap, ok := pk.(Signature); ok { pk = wrap.Unwrap() @@ -39,6 +47,7 @@ func WrapSignature(pk SignatureInner) Signature { return Signature{pk} } +// Unwrap recovers the concrete interface safely (regardless of levels of embeds) func (p Signature) Unwrap() SignatureInner { pk := p.SignatureInner for wrap, ok := pk.(Signature); ok; wrap, ok = pk.(Signature) {