github.com/mavryk-network/mvgo@v1.19.9/mavryk/address_test.go (about)

     1  // Copyright (c) 2020-2022 Blockwatch Data Inc.
     2  // Author: alex@blockwatch.cc
     3  
     4  package mavryk
     5  
     6  import (
     7  	"bytes"
     8  	"encoding/hex"
     9  	"testing"
    10  )
    11  
    12  func MustDecodeString(s string) []byte {
    13  	b, err := hex.DecodeString(s)
    14  	if err != nil {
    15  		panic(err)
    16  	}
    17  	return b
    18  }
    19  
    20  func TestAddress(t *testing.T) {
    21  	type testcase struct {
    22  		Address string
    23  		Hash    string
    24  		Type    AddressType
    25  		Bytes   string
    26  		Padded  string
    27  	}
    28  
    29  	cases := []testcase{
    30  		// mv1
    31  		{
    32  			Address: "mv1949pcbqwGsHfUCaVmNVRu21Cd4SnbpvpP",
    33  			Hash:    "0b78887fdd0cd3bfbe75a717655728e0205bb958",
    34  			Type:    AddressTypeEd25519,
    35  			Bytes:   "000b78887fdd0cd3bfbe75a717655728e0205bb958",
    36  			Padded:  "00000b78887fdd0cd3bfbe75a717655728e0205bb958",
    37  		},
    38  		// mv2
    39  		{
    40  			Address: "mv2h5E4ioj7VJVaQZcKxx4jZGH8wK45EEUxc",
    41  			Hash:    "e6e7cfd00186c29ede318bef62ac85ddec8a50d5",
    42  			Type:    AddressTypeSecp256k1,
    43  			Bytes:   "01e6e7cfd00186c29ede318bef62ac85ddec8a50d5",
    44  			Padded:  "0001e6e7cfd00186c29ede318bef62ac85ddec8a50d5",
    45  		},
    46  		// mv3
    47  		{
    48  			Address: "mv3CwX4KpwPXcoU9hw4VFtNUpkcadtynsrxB",
    49  			Hash:    "2e8671595e32ddd3c1e3f229898e9bec727eca90",
    50  			Type:    AddressTypeP256,
    51  			Bytes:   "022e8671595e32ddd3c1e3f229898e9bec727eca90",
    52  			Padded:  "00022e8671595e32ddd3c1e3f229898e9bec727eca90",
    53  		},
    54  		// KT1
    55  		{
    56  			Address: "KT1GyeRktoGPEKsWpchWguyy8FAf3aNHkw2T",
    57  			Hash:    "5c149d65c5ca113bc2bc3c861ef6ea8030d71553",
    58  			Type:    AddressTypeContract,
    59  			Bytes:   "015c149d65c5ca113bc2bc3c861ef6ea8030d7155300",
    60  			Padded:  "015c149d65c5ca113bc2bc3c861ef6ea8030d7155300",
    61  		},
    62  		// bmv1
    63  		{
    64  			Address: "bmv18hLJgDehQxwz2gN854tmDUJwunDhpUnNm",
    65  			Hash:    "000b80d92ce17aa6070fde1a99288a4213a5b650",
    66  			Type:    AddressTypeBlinded,
    67  			Bytes:   "03000b80d92ce17aa6070fde1a99288a4213a5b650",
    68  			Padded:  "0003000b80d92ce17aa6070fde1a99288a4213a5b650",
    69  		},
    70  		// TODO: AddressTypeSapling
    71  		// mv4
    72  		{
    73  			Address: "mv4VCVPHWd9rz1zua6iGm9SG6z8BmnST9pSE",
    74  			Hash:    "5d1497f39b87599983fe8f29599b679564be822d",
    75  			Type:    AddressTypeBls12_381,
    76  			Bytes:   "045d1497f39b87599983fe8f29599b679564be822d",
    77  			Padded:  "00045d1497f39b87599983fe8f29599b679564be822d",
    78  		},
    79  		// txr1
    80  		{
    81  			Address: "txr1QVAMSfhGduYQoQwrWroJW5b2796Qmb9ej",
    82  			Hash:    "202e50c8eed224f3961d83522039be4eee40633d",
    83  			Type:    AddressTypeTxRollup,
    84  			Bytes:   "02202e50c8eed224f3961d83522039be4eee40633d00",
    85  			Padded:  "02202e50c8eed224f3961d83522039be4eee40633d00",
    86  		},
    87  		// sr1
    88  		{
    89  			Address: "sr1Fq8fPi2NjhWUXtcXBggbL6zFjZctGkmso",
    90  			Hash:    "6b6209e8037138491d8d5d8ee340000d51b91581",
    91  			Type:    AddressTypeSmartRollup,
    92  			Bytes:   "036b6209e8037138491d8d5d8ee340000d51b9158100",
    93  			Padded:  "036b6209e8037138491d8d5d8ee340000d51b9158100",
    94  		},
    95  	}
    96  
    97  	for i, c := range cases {
    98  		h := MustDecodeString(c.Hash)
    99  		buf := MustDecodeString(c.Bytes)
   100  		pad := MustDecodeString(c.Padded)
   101  
   102  		// base58 must parse
   103  		a, err := ParseAddress(c.Address)
   104  		if err != nil {
   105  			t.Fatalf("Case %d - parsing address %s: %v", i, c.Address, err)
   106  		}
   107  
   108  		// check type
   109  		if got, want := a.Type(), c.Type; got != want {
   110  			t.Errorf("Case %d - mismatched type got=%s want=%s", i, got, want)
   111  		}
   112  
   113  		// check hash
   114  		if !bytes.Equal(a[1:], h) {
   115  			t.Errorf("Case %d - mismatched hash got=%x want=%x", i, a[1:], h)
   116  		}
   117  
   118  		// check bytes
   119  		if !bytes.Equal(a.Encode(), buf) {
   120  			t.Errorf("Case %d - mismatched binary encoding got=%x want=%x", i, a.Encode(), buf)
   121  		}
   122  
   123  		// check padded bytes
   124  		if !bytes.Equal(a.EncodePadded(), pad) {
   125  			t.Errorf("Case %d - mismatched padded binary encoding got=%x want=%x", i, a.EncodePadded(), pad)
   126  		}
   127  
   128  		// marshal text
   129  		out, err := a.MarshalText()
   130  		if err != nil {
   131  			t.Errorf("Case %d - marshal text unexpected error: %v", i, err)
   132  		}
   133  
   134  		if got, want := string(out), c.Address; got != want {
   135  			t.Errorf("Case %d - mismatched text encoding got=%s want=%s", i, got, want)
   136  		}
   137  
   138  		// unmarshal from bytes
   139  		var a2 Address
   140  		err = a2.Decode(buf)
   141  		if err != nil {
   142  			t.Fatalf("Case %d - unmarshal binary %s: %v", i, c.Bytes, err)
   143  		}
   144  
   145  		if !a2.Equal(a) {
   146  			t.Errorf("Case %d - mismatched address got=%s want=%s", i, a2, a)
   147  		}
   148  
   149  		// unmarshal from padded bytes
   150  		err = a2.Decode(pad)
   151  		if err != nil {
   152  			t.Fatalf("Case %d - unmarshal binary %s: %v", i, c.Padded, err)
   153  		}
   154  
   155  		if !a2.Equal(a) {
   156  			t.Errorf("Case %d - mismatched address got=%s want=%s", i, a2, a)
   157  		}
   158  
   159  		// unmarshal text
   160  		err = a2.UnmarshalText([]byte(c.Address))
   161  		if err != nil {
   162  			t.Fatalf("Case %d - unmarshal text %s: %v", i, c.Address, err)
   163  		}
   164  
   165  		if !a2.Equal(a) {
   166  			t.Errorf("Case %d - mismatched address got=%s want=%s", i, a2, a)
   167  		}
   168  
   169  		// marshal binary roundtrip
   170  		out = a.Encode()
   171  		err = a2.Decode(out)
   172  		if err != nil {
   173  			t.Fatalf("Case %d - binary roundtrip: %v", i, err)
   174  		}
   175  
   176  		if !a2.Equal(a) {
   177  			t.Errorf("Case %d - mismatched binary roundtrip got=%s want=%s", i, a2, a)
   178  		}
   179  	}
   180  }
   181  
   182  func TestInvalidAddress(t *testing.T) {
   183  	// invalid base58 string
   184  	if _, err := ParseAddress("mv1KzpjBnunNJVABHBnzfG4iuLmphitExW2"); err == nil {
   185  		t.Errorf("Expected error on invalid base58 string")
   186  	}
   187  
   188  	// init from invalid short hash
   189  	hash := MustDecodeString("0b78887fdd0cd3bfbe75a717655728e0205bb9")
   190  	a := NewAddress(AddressTypeEd25519, hash)
   191  	if a.IsValid() {
   192  		t.Errorf("Expected invalid address from short hash")
   193  	}
   194  
   195  	// init from invalid empty bytes
   196  	a = NewAddress(AddressTypeEd25519, nil)
   197  	if a.IsValid() {
   198  		t.Errorf("Expected invalid address from nil hash")
   199  	}
   200  
   201  	// decode from short buffer
   202  	err := a.Decode(MustDecodeString("000b78887fdd0cd3bfbe75a717655728e0205bb9"))
   203  	if err == nil || a.IsValid() {
   204  		t.Errorf("Expected unmarshal error from short buffer")
   205  	}
   206  
   207  	// decode from nil buffer
   208  	err = a.Decode(nil)
   209  	if err == nil || a.IsValid() {
   210  		t.Errorf("Expected unmarshal error from short buffer")
   211  	}
   212  
   213  	// decode from invalid buffer (wrong type)
   214  	err = a.Decode(MustDecodeString("00FF000b80d92ce17aa6070fde1a99288a4213a5b650"))
   215  	if err == nil || a.IsValid() {
   216  		t.Errorf("Expected unmarshal error from invalid buffer")
   217  	}
   218  }
   219  
   220  func BenchmarkAddressDecode(b *testing.B) {
   221  	b.SetBytes(21)
   222  	b.ReportAllocs()
   223  	for i := 0; i < b.N; i++ {
   224  		_, _ = ParseAddress("mv3CwX4KpwPXcoU9hw4VFtNUpkcadtynsrxB")
   225  	}
   226  }
   227  
   228  func BenchmarkAddressEncode(b *testing.B) {
   229  	a, _ := ParseAddress("mv3CwX4KpwPXcoU9hw4VFtNUpkcadtynsrxB")
   230  	b.SetBytes(21)
   231  	b.ReportAllocs()
   232  	for i := 0; i < b.N; i++ {
   233  		_ = a.String()
   234  	}
   235  }