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

     1  // Copyright (c) 2023 Blockwatch Data Inc.
     2  // Author: alex@blockwatch.cc
     3  
     4  package mavryk
     5  
     6  import (
     7  	"bytes"
     8  	"encoding"
     9  	"encoding/binary"
    10  
    11  	// "encoding/hex"
    12  	"fmt"
    13  	"testing"
    14  )
    15  
    16  type Marshallable interface {
    17  	encoding.TextUnmarshaler
    18  	encoding.BinaryUnmarshaler
    19  	fmt.Stringer
    20  }
    21  
    22  func TestHash(t *testing.T) {
    23  	type testcase struct {
    24  		String string
    25  		Bytes  []byte
    26  		Type   HashType
    27  		Val    Marshallable
    28  	}
    29  
    30  	cases := []testcase{
    31  		// chain id
    32  		{
    33  			String: "NetXdQprcVkpaWU",
    34  			Bytes:  MustDecodeString("7a06a770"),
    35  			Type:   HashTypeChainId,
    36  			Val:    &ChainIdHash{},
    37  		},
    38  		// block
    39  		{
    40  			String: "BKjS7rtCjysnMNWUuevZiF2a6NkUas9bnSsNQ3ibh5GfKNrQoGk",
    41  			Bytes:  MustDecodeString("029d4ed3161d644bedccb8673f30c6682b6e0a11756a3f75d7a739dede1cf29e"),
    42  			Type:   HashTypeBlock,
    43  			Val:    &BlockHash{},
    44  		},
    45  		// protocol
    46  		{
    47  			String: "PtLimaPtLMwfNinJi9rCfDPWea8dFgTZ1MeJ9f1m2SRic6ayiwW",
    48  			Bytes:  MustDecodeString("d57ed88be5a69815e39386a33f7dcad391f5f507e03b376e499272c86c6cf2a7"),
    49  			Type:   HashTypeProtocol,
    50  			Val:    &ProtocolHash{},
    51  		},
    52  		// op
    53  		{
    54  			String: "oogC8ju9tMDqeB6RiAXdch3hnt8u3Pbf2ZXyyhAmJAhjQ4q1wUS",
    55  			Bytes:  MustDecodeString("88315c911f6b4c38b2d8ea27319cf91d3614e1dde486dc83d55cd47bfbc568b4"),
    56  			Type:   HashTypeOperation,
    57  			Val:    &OpHash{},
    58  		},
    59  		// op list list
    60  		{
    61  			String: "LLoZnUuxzhNESHg7HvXxoccUCvWPrVmAucjaJDfKBeea39LqyVKEP",
    62  			Bytes:  MustDecodeString("3ccb42fba1b24ce6c4e99ed1c4674dc90542d9fbc5694b9220ed74feb0eb3507"),
    63  			Type:   HashTypeOperationListList,
    64  			Val:    &OpListListHash{},
    65  		},
    66  		// payload
    67  		{
    68  			String: "vh26kqZ6LeKwygSY9JYZbqSdhtRjphAcrSEJqJ6a8EgnQEMtQx8J",
    69  			Bytes:  MustDecodeString("37eec128736b994b3ce44a36c81dd00b2eab68057c11900a8135eaa5bff606fa"),
    70  			Type:   HashTypeBlockPayload,
    71  			Val:    &PayloadHash{},
    72  		},
    73  		// expr
    74  		{
    75  			String: "expruPBWMccKybChcJmGF8oMo263Ri6HgbKbAJRS8j6GbmqZJPJfVG",
    76  			Bytes:  MustDecodeString("72386e5b4dbe9cc415bb0d909fe63e3162bc4b662ea4bfc92c485ad12f6700e8"),
    77  			Type:   HashTypeScriptExpr,
    78  			Val:    &ExprHash{},
    79  		},
    80  		// nonce
    81  		{
    82  			String: "nceUcirB7QYmVgcNUYQvd1fTzqSHjyusoE8VmJX9SNgELeQ4ffdcr",
    83  			Bytes:  MustDecodeString("33b55c290efcc31f235a3809198ff324b31c65088a18815b8c67bf5ed1567dcd"),
    84  			Type:   HashTypeNonce,
    85  			Val:    &NonceHash{},
    86  		},
    87  		// context
    88  		{
    89  			String: "CoWAJ6dKTDySvhrV5njZwHpckRSBgzb84vXZKrEd1AwyshxFb9vo",
    90  			Bytes:  MustDecodeString("c7c8fad1f5d2c144edbc763dc4e009c1fca3637dd265ae2c0044168065986b2b"),
    91  			Type:   HashTypeContext,
    92  			Val:    &ContextHash{},
    93  		},
    94  	}
    95  
    96  	for i, c := range cases {
    97  		// base58 must parse
    98  		if err := c.Val.UnmarshalText([]byte(c.String)); err != nil {
    99  			t.Fatalf("Case %d - unmarshal %s hash %s: %v", i, c.Type, c.String, err)
   100  		}
   101  
   102  		// write binary
   103  		buf := new(bytes.Buffer)
   104  		err := binary.Write(buf, binary.LittleEndian, c.Val)
   105  		if err != nil {
   106  			t.Fatalf("Case %d - write binary for hash %s: %v", i, c.String, err)
   107  		}
   108  
   109  		// check binary
   110  		if !bytes.Equal(buf.Bytes(), c.Bytes) {
   111  			t.Errorf("Case %d - mismatched hash got=%x want=%x", i, buf.Bytes(), c.Bytes)
   112  		}
   113  
   114  		// unmarshal from bytes
   115  		if err := c.Val.UnmarshalBinary(c.Bytes); err != nil {
   116  			t.Fatalf("Case %d - unmarshal binary %s: %v", i, c.Bytes, err)
   117  		}
   118  
   119  		// marshal text
   120  		s := c.Val.String()
   121  
   122  		// check text
   123  		if s != c.String {
   124  			t.Errorf("Case %d - mismatched text encoding got=%x want=%x", i, s, c.String)
   125  		}
   126  	}
   127  }
   128  
   129  func TestInvalidHash(t *testing.T) {
   130  	// invalid base58 string
   131  	if _, err := ParseBlockHash("mv1KzpjBnunNJVABHBnzfG4iuLmphitExW2"); err == nil {
   132  		t.Errorf("Expected error on invalid base58 string")
   133  	}
   134  
   135  	// decode from short buffer
   136  	var b BlockHash
   137  	err := b.UnmarshalBinary(MustDecodeString("000b78887fdd0cd3bfbe75a717655728e0205bb9"))
   138  	if err == nil {
   139  		t.Errorf("Expected unmarshal error from short buffer")
   140  	}
   141  
   142  	// decode from nil buffer is OK
   143  	err = b.UnmarshalBinary(nil)
   144  	if err != nil {
   145  		t.Errorf("Expected no unmarshal error from nil buffer, got %v", err)
   146  	}
   147  
   148  	// decode from empty string is OK
   149  	err = b.UnmarshalText(nil)
   150  	if err != nil {
   151  		t.Errorf("Expected no unmarshal error from null string, got %v", err)
   152  	}
   153  }
   154  
   155  func BenchmarkHashDecode(b *testing.B) {
   156  	b.SetBytes(32)
   157  	b.ReportAllocs()
   158  	for i := 0; i < b.N; i++ {
   159  		_, _ = ParseBlockHash("BKjS7rtCjysnMNWUuevZiF2a6NkUas9bnSsNQ3ibh5GfKNrQoGk")
   160  	}
   161  }
   162  
   163  func BenchmarkHashEncode(b *testing.B) {
   164  	b.SetBytes(32)
   165  	b.ReportAllocs()
   166  	for i := 0; i < b.N; i++ {
   167  		_ = ZeroBlockHash.String()
   168  	}
   169  }