solana-go/keys_test.go

246 lines
5.8 KiB
Go

package solana
import (
"encoding/hex"
"errors"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestPublicKeyFromBytes(t *testing.T) {
tests := []struct {
name string
inHex string
expected PublicKey
}{
{
"empty",
"",
MustPublicKeyFromBase58("11111111111111111111111111111111"),
},
{
"smaller than required",
"010203040506",
MustPublicKeyFromBase58("4wBqpZM9k69W87zdYXT2bRtLViWqTiJV3i2Kn9q7S6j"),
},
{
"equal to 32 bytes",
"0102030405060102030405060102030405060102030405060102030405060101",
MustPublicKeyFromBase58("4wBqpZM9msxygzsdeLPq6Zw3LoiAxJk3GjtKPpqkcsi"),
},
{
"longer than required",
"0102030405060102030405060102030405060102030405060102030405060101FFFFFFFFFF",
MustPublicKeyFromBase58("4wBqpZM9msxygzsdeLPq6Zw3LoiAxJk3GjtKPpqkcsi"),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
bytes, err := hex.DecodeString(test.inHex)
require.NoError(t, err)
actual := PublicKeyFromBytes(bytes)
assert.Equal(t, test.expected, actual, "%s != %s", test.expected, actual)
})
}
}
func TestPublicKeyFromBase58(t *testing.T) {
tests := []struct {
name string
in string
expected PublicKey
expectedErr error
}{
{
"hand crafted",
"SerumkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
MustPublicKeyFromBase58("SerumkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"),
nil,
},
{
"hand crafted error",
"SerkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
zeroPublicKey,
errors.New("invalid length, expected 32, got 30"),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
actual, err := PublicKeyFromBase58(test.in)
if test.expectedErr == nil {
require.NoError(t, err)
assert.Equal(t, test.expected, actual)
} else {
assert.Equal(t, test.expectedErr, err)
}
})
}
}
func TestPrivateKeyFromSolanaKeygenFile(t *testing.T) {
tests := []struct {
inFile string
expected PrivateKey
expectedPub PublicKey
expectedErr error
}{
{
"testdata/standard.solana-keygen.json",
MustPrivateKeyFromBase58("66cDvko73yAf8LYvFMM3r8vF5vJtkk7JKMgEKwkmBC86oHdq41C7i1a2vS3zE1yCcdLLk6VUatUb32ZzVjSBXtRs"),
MustPublicKeyFromBase58("F8UvVsKnzWyp2nF8aDcqvQ2GVcRpqT91WDsAtvBKCMt9"),
nil,
},
}
for _, test := range tests {
t.Run(test.inFile, func(t *testing.T) {
actual, err := PrivateKeyFromSolanaKeygenFile(test.inFile)
if test.expectedErr == nil {
require.NoError(t, err)
assert.Equal(t, test.expected, actual)
assert.Equal(t, test.expectedPub, actual.PublicKey(), "%s != %s", test.expectedPub, actual.PublicKey())
} else {
assert.Equal(t, test.expectedErr, err)
}
})
}
}
func TestPublicKey_MarshalText(t *testing.T) {
keyString := "4wBqpZM9k69W87zdYXT2bRtLViWqTiJV3i2Kn9q7S6j"
keyParsed := MustPublicKeyFromBase58(keyString)
var key PublicKey
err := key.UnmarshalText([]byte(keyString))
require.NoError(t, err)
assert.True(t, keyParsed.Equals(key))
keyText, err := key.MarshalText()
require.NoError(t, err)
assert.Equal(t, []byte(keyString), keyText)
type IdentityToSlotsBlocks map[PublicKey][2]int64
var payload IdentityToSlotsBlocks
data := `{"` + keyString + `":[3,4]}`
err = json.Unmarshal([]byte(data), &payload)
require.NoError(t, err)
assert.Equal(t,
IdentityToSlotsBlocks{
keyParsed: [2]int64{3, 4},
},
payload,
)
}
func TestPublicKeySlice(t *testing.T) {
slice := make(PublicKeySlice, 0)
require.False(t, slice.Has(BPFLoaderProgramID))
slice.Append(BPFLoaderProgramID)
require.True(t, slice.Has(BPFLoaderProgramID))
require.Len(t, slice, 1)
slice.UniqueAppend(BPFLoaderProgramID)
require.Len(t, slice, 1)
slice.Append(ConfigProgramID)
require.Len(t, slice, 2)
require.True(t, slice.Has(ConfigProgramID))
}
func TestIsNativeProgramID(t *testing.T) {
require.True(t, isNativeProgramID(ConfigProgramID))
}
func TestCreateWithSeed(t *testing.T) {
{
got, err := CreateWithSeed(PublicKey{}, "limber chicken: 4/45", PublicKey{})
require.NoError(t, err)
require.True(t, got.Equals(MustPublicKeyFromBase58("9h1HyLCW5dZnBVap8C5egQ9Z6pHyjsh5MNy83iPqqRuq")))
}
}
func TestCreateProgramAddress(t *testing.T) {
program_id := MustPublicKeyFromBase58("BPFLoaderUpgradeab1e11111111111111111111111")
public_key := MustPublicKeyFromBase58("SeedPubey1111111111111111111111111111111111")
{
got, err := CreateProgramAddress([][]byte{
{},
{1},
},
program_id,
)
require.NoError(t, err)
require.True(t, got.Equals(MustPublicKeyFromBase58("BwqrghZA2htAcqq8dzP1WDAhTXYTYWj7CHxF5j7TDBAe")))
}
{
got, err := CreateProgramAddress([][]byte{
[]byte("☉"),
{0},
},
program_id,
)
require.NoError(t, err)
require.True(t, got.Equals(MustPublicKeyFromBase58("13yWmRpaTR4r5nAktwLqMpRNr28tnVUZw26rTvPSSB19")))
}
{
got, err := CreateProgramAddress([][]byte{
[]byte("Talking"),
[]byte("Squirrels"),
},
program_id,
)
require.NoError(t, err)
require.True(t, got.Equals(MustPublicKeyFromBase58("2fnQrngrQT4SeLcdToJAD96phoEjNL2man2kfRLCASVk")))
}
{
got, err := CreateProgramAddress([][]byte{
public_key[:],
{1},
},
program_id,
)
require.NoError(t, err)
require.True(t, got.Equals(MustPublicKeyFromBase58("976ymqVnfE32QFe6NfGDctSvVa36LWnvYxhU6G2232YL")))
}
}
// https://github.com/solana-labs/solana/blob/216983c50e0a618facc39aa07472ba6d23f1b33a/sdk/program/src/pubkey.rs#L590
func TestFindProgramAddress(t *testing.T) {
for i := 0; i < 1_000; i++ {
program_id := NewWallet().PrivateKey.PublicKey()
address, bump_seed, err := FindProgramAddress(
[][]byte{
[]byte("Lil'"),
[]byte("Bits"),
},
program_id,
)
require.NoError(t, err)
got, err := CreateProgramAddress(
[][]byte{
[]byte("Lil'"),
[]byte("Bits"),
[]byte{bump_seed},
},
program_id,
)
require.NoError(t, err)
require.Equal(t, address, got)
}
}