github.com/gagliardetto/solana-go@v1.11.0/nativetype_test.go (about)

     1  // Copyright 2021 github.com/gagliardetto
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package solana
    16  
    17  import (
    18  	"encoding/base64"
    19  	"strconv"
    20  	"testing"
    21  
    22  	"github.com/mr-tron/base58"
    23  	"github.com/stretchr/testify/assert"
    24  	"github.com/stretchr/testify/require"
    25  )
    26  
    27  func TestMustHashFromBase58(t *testing.T) {
    28  	require.Panics(t, func() {
    29  		MustHashFromBase58("toto")
    30  	})
    31  }
    32  
    33  func TestHash_UnmarshalText(t *testing.T) {
    34  	in := MustHashFromBase58("uoEAQCWCKjV9ecsBvngctJ7upNBZX7hpN4SfdR6TaUz")
    35  
    36  	out, err := in.MarshalText()
    37  	assert.NoError(t, err)
    38  
    39  	var ha Hash
    40  	err = ha.UnmarshalText(out)
    41  	assert.NoError(t, err)
    42  	assert.Equal(t, in, ha)
    43  }
    44  
    45  func TestHashFromBase58(t *testing.T) {
    46  	in := "uoEAQCWCKjV9ecsBvngctJ7upNBZX7hpN4SfdR6TaUz"
    47  	out, err := HashFromBase58(in)
    48  	assert.NoError(t, err)
    49  	assert.Equal(t, in, out.String())
    50  
    51  	jsonOut, err := out.MarshalJSON()
    52  	assert.NoError(t, err)
    53  	assert.Equal(t, strconv.Quote(in), string(jsonOut))
    54  
    55  	var ha Hash
    56  	assert.True(t, ha.IsZero())
    57  	err = ha.UnmarshalJSON(jsonOut)
    58  	assert.NoError(t, err)
    59  	assert.Equal(t, out, ha)
    60  	assert.True(t, out.Equals(ha))
    61  	assert.False(t, out.Equals(Hash{}))
    62  	assert.False(t, out.IsZero())
    63  }
    64  
    65  func TestSignature_UnmarshalText(t *testing.T) {
    66  	in := MustSignatureFromBase58("gD3jeeaPNiyuJvTKXNEv1gntazWEkvpocofEmrz2rL6Fi4prWSsBH6a9SrwyZEatAozyMsnK2fnk3APXNFxD2Mq")
    67  
    68  	out, err := in.MarshalText()
    69  	assert.NoError(t, err)
    70  
    71  	var sig Signature
    72  	err = sig.UnmarshalText(out)
    73  	assert.NoError(t, err)
    74  	assert.Equal(t, in, sig)
    75  }
    76  
    77  func TestSignatureFromBase58(t *testing.T) {
    78  	in := "gD3jeeaPNiyuJvTKXNEv1gntazWEkvpocofEmrz2rL6Fi4prWSsBH6a9SrwyZEatAozyMsnK2fnk3APXNFxD2Mq"
    79  	out, err := SignatureFromBase58(in)
    80  	assert.NoError(t, err)
    81  	assert.Equal(t, in, out.String())
    82  
    83  	jsonOut, err := out.MarshalJSON()
    84  	assert.NoError(t, err)
    85  	assert.Equal(t, strconv.Quote(in), string(jsonOut))
    86  
    87  	var sig Signature
    88  	assert.True(t, sig.IsZero())
    89  	err = sig.UnmarshalJSON(jsonOut)
    90  	assert.NoError(t, err)
    91  	assert.Equal(t, out, sig)
    92  	assert.True(t, out.Equals(sig))
    93  	assert.False(t, out.Equals(Signature{}))
    94  	assert.False(t, out.IsZero())
    95  }
    96  
    97  func TestMustSignatureFromBase58(t *testing.T) {
    98  	require.Panics(t, func() {
    99  		MustSignatureFromBase58("toto")
   100  	})
   101  }
   102  
   103  func TestBase58(t *testing.T) {
   104  	in := "RYcCwZg97M2jet84ttG8"
   105  
   106  	out, err := base58.Decode(in)
   107  	assert.NoError(t, err)
   108  	assert.Equal(t, in, Base58(out).String())
   109  
   110  	jsonOut, err := Base58(out).MarshalJSON()
   111  	assert.NoError(t, err)
   112  	assert.Equal(t, strconv.Quote(in), string(jsonOut))
   113  
   114  	var b58 Base58
   115  	err = b58.UnmarshalJSON(jsonOut)
   116  	assert.NoError(t, err)
   117  }
   118  
   119  func TestData_base64(t *testing.T) {
   120  	val := "dGVzdA=="
   121  	in := `["` + val + `", "base64"]`
   122  
   123  	var data Data
   124  	err := data.UnmarshalJSON([]byte(in))
   125  	assert.NoError(t, err)
   126  
   127  	assert.Equal(t,
   128  		[]byte("test"),
   129  		data.Content,
   130  	)
   131  
   132  	assert.Equal(t,
   133  		EncodingBase64,
   134  		data.Encoding,
   135  	)
   136  
   137  	assert.Equal(t,
   138  		[]interface{}{
   139  			val,
   140  			"base64",
   141  		},
   142  		mustJSONToInterface(mustAnyToJSON(data)),
   143  	)
   144  }
   145  
   146  func TestData_base64_empty(t *testing.T) {
   147  	val := ""
   148  	in := `["", "base64"]`
   149  
   150  	var data Data
   151  	err := data.UnmarshalJSON([]byte(in))
   152  	assert.NoError(t, err)
   153  
   154  	assert.Equal(t,
   155  		[]byte(""),
   156  		data.Content,
   157  	)
   158  
   159  	assert.Equal(t,
   160  		EncodingBase64,
   161  		data.Encoding,
   162  	)
   163  
   164  	assert.Equal(t,
   165  		[]interface{}{
   166  			val,
   167  			"base64",
   168  		},
   169  		mustJSONToInterface(mustAnyToJSON(data)),
   170  	)
   171  }
   172  
   173  func TestData_base64_zstd(t *testing.T) {
   174  	val := "KLUv/QQAWQAAaGVsbG8td29ybGTcLcaB"
   175  	in := `["` + val + `", "base64+zstd"]`
   176  
   177  	var data Data
   178  	err := data.UnmarshalJSON([]byte(in))
   179  	assert.NoError(t, err)
   180  
   181  	assert.Equal(t,
   182  		[]byte("hello-world"),
   183  		data.Content,
   184  	)
   185  
   186  	assert.Equal(t,
   187  		EncodingBase64Zstd,
   188  		data.Encoding,
   189  	)
   190  
   191  	assert.Equal(t,
   192  		[]interface{}{
   193  			val,
   194  			"base64+zstd",
   195  		},
   196  		mustJSONToInterface(mustAnyToJSON(data)),
   197  	)
   198  }
   199  
   200  func TestData_base64_zstd_empty(t *testing.T) {
   201  	in := `["", "base64+zstd"]`
   202  
   203  	var data Data
   204  	err := data.UnmarshalJSON([]byte(in))
   205  	assert.NoError(t, err)
   206  
   207  	assert.Equal(t,
   208  		[]byte(""),
   209  		data.Content,
   210  	)
   211  
   212  	assert.Equal(t,
   213  		EncodingBase64Zstd,
   214  		data.Encoding,
   215  	)
   216  
   217  	assert.Equal(t,
   218  		[]interface{}{
   219  			"",
   220  			"base64+zstd",
   221  		},
   222  		mustJSONToInterface(mustAnyToJSON(data)),
   223  	)
   224  }
   225  
   226  func TestData_base58(t *testing.T) {
   227  	val := "3yZe7d"
   228  	in := `["` + val + `", "base58"]`
   229  
   230  	var data Data
   231  	err := data.UnmarshalJSON([]byte(in))
   232  	assert.NoError(t, err)
   233  
   234  	assert.Equal(t,
   235  		[]byte("test"),
   236  		data.Content,
   237  	)
   238  
   239  	assert.Equal(t,
   240  		EncodingBase58,
   241  		data.Encoding,
   242  	)
   243  
   244  	assert.Equal(t,
   245  		[]interface{}{
   246  			val,
   247  			"base58",
   248  		},
   249  		mustJSONToInterface(mustAnyToJSON(data)),
   250  	)
   251  }
   252  
   253  func TestData_base58_empty(t *testing.T) {
   254  	val := ""
   255  	in := `["", "base58"]`
   256  
   257  	var data Data
   258  	err := data.UnmarshalJSON([]byte(in))
   259  	assert.NoError(t, err)
   260  
   261  	assert.Equal(t,
   262  		[]byte(""),
   263  		data.Content,
   264  	)
   265  
   266  	assert.Equal(t,
   267  		EncodingBase58,
   268  		data.Encoding,
   269  	)
   270  
   271  	assert.Equal(t,
   272  		[]interface{}{
   273  			val,
   274  			"base58",
   275  		},
   276  		mustJSONToInterface(mustAnyToJSON(data)),
   277  	)
   278  }
   279  
   280  // mustAnyToJSON marshals the provided variable
   281  // to JSON bytes.
   282  func mustAnyToJSON(raw interface{}) []byte {
   283  	out, err := json.Marshal(raw)
   284  	if err != nil {
   285  		panic(err)
   286  	}
   287  	return out
   288  }
   289  
   290  // mustJSONToInterface unmarshals the provided JSON bytes
   291  // into an `interface{}` type variable, and returns it.
   292  func mustJSONToInterface(rawJSON []byte) interface{} {
   293  	var out interface{}
   294  	err := json.Unmarshal(rawJSON, &out)
   295  	if err != nil {
   296  		panic(err)
   297  	}
   298  	return out
   299  }
   300  
   301  func TestMustPublicKeyFromBase58(t *testing.T) {
   302  	require.Panics(t, func() {
   303  		MustPublicKeyFromBase58("toto")
   304  	})
   305  }
   306  
   307  func TestSignatureVerify(t *testing.T) {
   308  	type signerSignature struct {
   309  		Sig    Signature
   310  		Signer PublicKey
   311  	}
   312  	type testCase struct {
   313  		Message string
   314  		Signers []signerSignature
   315  	}
   316  
   317  	testCases := []testCase{
   318  		{
   319  			Signers: []signerSignature{
   320  				{
   321  					Sig:    MustSignatureFromBase58("3APVUYY2Qcq9WwPSciQ1xicshQcsXJWhgD1x5YEMNnNnKtpaAJtRhDVMWcvePosamk3JfSKpBM8qt5ZkAQgRNSzo"),
   322  					Signer: MustPublicKeyFromBase58("2V7t5NaKY7aGkwytCWQgvUYZfEr9XMwNChhJEakTExk6"),
   323  				},
   324  			},
   325  			Message: "AQACBBYPusE6993YBdMXCj3gxr2XEmoeAsDSWdCobvgh1uXHoaZGX0wuvyRMMdgLyVwnNFo0JOQowt7zPs7Z6Q0/cBsGp9UXGMd0yShWY5hpHV62i164o5tLbVxzVVshAAAAANzl6+HknDufEUy1VExQqZ7A1pLWP1Z5WuAprIPZ6ovia//gAIGoVfMJgSuJp8/VsCUq8qvMdiHNGrMrQAxoS2QBAwMAAQIoAgAAAAcAAAABAAAAAAAAAM/ncrkCAAAACJ9fAQAAAAD7FSgHAAAAAA==",
   326  		},
   327  		{
   328  			Signers: []signerSignature{
   329  				{
   330  					Sig:    MustSignatureFromBase58("5TPaoKhkhRck3TTjyEQe1TbgXHATggx9iyWaXqj7foCUSuXnVUh3iqMrKKndWZn31cV3KEiBDiqg9wM8ijk41eyQ"),
   331  					Signer: MustPublicKeyFromBase58("G2fzpkX69kmaYtDtMfUkQHykSvgV24wze9ikb911FHT"),
   332  				},
   333  			},
   334  			Message: "AQADBQPZmmOEu9u2f5Tkm9PJx3oVRbAt9pEyjDD4zyadddWyjNBZdQ4NOL1dsfZy9kwqkh5o0/MYOsFAM42WtfumAgUGp9UXGS8Kr8byZeP7d8x62oLFKdC+OxNuLQBVIAAAAAan1RcYx3TJKFZjmGkdXraLXrijm0ttXHNVWyEAAAAAB2FIHTV0dLt8TXYk69O9s9g1XnPREEP8DaNTgAAAAACQ0H7JStckBZBqg11runLYUTbmBpWo2DDpraEiQeoZjwEEBAECAwBNAgAAAAMAAAAAAAAA+RUoBwAAAAD6FSgHAAAAAPsVKAcAAAAAxAjCTj1+3u3zheR66vcYXXIdlKoYPL0DmMmTP+lffN4B0NIDYgAAAAA=",
   335  		},
   336  		{
   337  			Signers: []signerSignature{
   338  				{
   339  					Sig:    MustSignatureFromBase58("T1BbonhT8wdLpRMPN8UAtshjukRwot8Z5ta7wSaHujSfrqKuFpQD56iwa5hjESMzsNKFpzPVETCVZ54puCiZh2y"),
   340  					Signer: MustPublicKeyFromBase58("3jBp2LRCFgSmBS1Qemji1rHWS9ytSoN5pYpWzK5o9CDY"),
   341  				},
   342  			},
   343  			Message: "AQACBSiF/dgUa5IBH6yxFwL17cOzoDz4R1PutgvAweUD6DIDUmyl4Hbm9LK+2Kdzb3a7Kekg6CeIHaMkWndgFfiWqY9HUbWFuDsRO/Bb0WU3qhxctjMv5tdv2nxiD0vIlJzBpQan1RcYx3TJKFZjmGkdXraLXrijm0ttXHNVWyEAAAAAv47fHJRrVrtD0l+YuHtr5REXMAphJhr5+flO7XpagIiuIXQDe/BrXhY6rSa8S18aVTSrLtZX3XBT12vynIOHuQEEBAEAAwInJjIkEAIhro89MaE0EkAoADDzq6A5ORdIUPwYMxJAQb1SliGONRJA",
   344  		},
   345  		{
   346  			Signers: []signerSignature{
   347  				{
   348  					Sig:    MustSignatureFromBase58("2c5u22N6Yyjj7qQdGtEshp4n9r4akLyRLJijnXL9HnQAXqq7S9cfnGdi5mwnfQ5kJHQuRv62T366SKaztHiUUqnK"),
   349  					Signer: MustPublicKeyFromBase58("AXUChvpRwUUPMJhA4d23WcoyAL7W8zgAeo7KoH57c75F"),
   350  				},
   351  			},
   352  			Message: "AQACBo2HXSJ3fw0pdiiQj9fBoRA5Wicjyla4ARhrK90xeo0mD4K9wHSEzSq9lEFUOSPloeUrUL/2uV3S6+lTeGNtTMtTP2NRTSucECyiWtS2HzfxwLnbnxVbXNH0T0egDFCfVK5ESO7I2Pz56XFyxewO0gbya1rvqPPu0CGg/LC/Wl5BhQ8tbgKkevgk0Jq2ncQtcMsoy/okn7fuV7nSVsEnYu8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIvotbwkk/hzTtAxHIaRCSJjB4WdQUXrn+6aEapl6XgPAgQFAQIDAgIHAAMAAAABAAUCAAAMAgAAAOsNAAAAAAAA",
   353  		},
   354  		{
   355  			Signers: []signerSignature{
   356  				{
   357  					Sig:    MustSignatureFromBase58("2amhinnUjRMef8aNMKKhGCf4odSR3q9Tq2SjYjvFePN6ZmStF5EbNmfdsqssXe4XjXn6Nidu1Sg4MKyo5UPVWQgf"),
   358  					Signer: MustPublicKeyFromBase58("2vKtu3nW1TS6iPvJPK8R88B5QfDrwJDwwB11Uu1CN9o7"),
   359  				},
   360  				{
   361  					Sig:    MustSignatureFromBase58("5qzhXaDMhcVZA2y6KDK218noKdX7cd7aRCC1XvFFUTEievDMt8EbCC1oCKyqGvGmZs5UzE34v9JR8846HtJVF6qe"),
   362  					Signer: MustPublicKeyFromBase58("96i77Hg7RL7J4Lrc1d6MXFofCKwEFZe84DejFUMhUs19"),
   363  				},
   364  			},
   365  			Message: "AgEBBByE1Y6EqCJKsr7iEupU6lsBHtBdtI4SK3yWMCFA0iEKeFPgnGmtp+1SIX1Ak+sN65iBaR7v4Iim5m1OEuFQTgi9N57UnhNpCNuUePaTt7HJaFBmyeZB3deXeKWVudpY3gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWVECK/n3a7QR6OKWYR4DuAVjS6FXgZj82W0dJpSIPnEBAwQAAgEDDAIAAABAQg8AAAAAAA==",
   366  		},
   367  	}
   368  
   369  	for _, tc := range testCases {
   370  		msg, err := base64.StdEncoding.DecodeString(tc.Message)
   371  		require.NoError(t, err)
   372  
   373  		for _, tcs := range tc.Signers {
   374  			require.True(t, tcs.Sig.Verify(tcs.Signer, msg))
   375  			require.False(t, tcs.Sig.Verify(BPFLoaderDeprecatedProgramID, msg))
   376  			require.True(t, tcs.Signer.Verify(msg, tcs.Sig))
   377  		}
   378  	}
   379  }