246 lines
5.8 KiB
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)
|
|
}
|
|
}
|