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

     1  // Copyright (c) 2020-2022 Blockwatch Data Inc.
     2  // Author: alex@blockwatch.cc
     3  
     4  package codec
     5  
     6  import (
     7  	"bytes"
     8  	"testing"
     9  
    10  	"github.com/mavryk-network/mvgo/mavryk"
    11  )
    12  
    13  func TestBlock(t *testing.T) {
    14  	type testcase struct {
    15  		data  mavryk.HexBytes
    16  		head  BlockHeader
    17  		chain mavryk.ChainIdHash
    18  		hash  mavryk.BlockHash
    19  		key   mavryk.PrivateKey
    20  		sig   mavryk.Signature
    21  	}
    22  
    23  	var cases = []testcase{
    24  		// Tenderbake block
    25  		{
    26  			data: asHex("0004ad5702d21acd0569ff8e03cd564fdc15baae8e436b141510f4ca966bdadfe092904359000000006242e26904cf318e718893b9efb0a426130f6d8fac752db1c47a98d0c3f89780ec8b1a4740000000210000000102000000040004ad570000000000000004ffffffff00000004000000016ae0589f63d96d15d6b41b4e9a9c6f5670ae7e4a3495ffdaf0fa651a10b9e25d9253ed831d88bb031de4f49e43d62977864806a7b0945e8877b030150f2ae63b00000001df2ea592260c01000000"),
    27  			head: BlockHeader{
    28  				Level:          306519,
    29  				Proto:          2,
    30  				Predecessor:    mavryk.MustParseBlockHash("BMJpBGs6rDpEGki8vLVd6VAcLrnEnAhxAwpGjExRcT8qDCmwQQm"),
    31  				Timestamp:      asTime("2022-03-29T10:41:45Z"),
    32  				ValidationPass: 4,
    33  				OperationsHash: mavryk.MustParseOpListListHash("LLoatxVfWnkjHGYBuXL6ELtKqkX1EvLr5ffHSd5pySMY88AY2MeMr"),
    34  				Fitness: []mavryk.HexBytes{
    35  					asHex("02"),
    36  					asHex("0004ad57"),
    37  					asHex(""),
    38  					asHex("ffffffff"),
    39  					asHex("00000001"),
    40  				},
    41  				Context:          mavryk.MustParseContextHash("CoVTNsN2t3DU6m6nL2HL3qEzCA2jhiUEAnWZde7dPmzcdm61EYBp"),
    42  				PayloadHash:      mavryk.MustParsePayloadHash("vh2nZrxixzv4ZjAJn7PRj79GumUMAJzxuEYMjo496TYSaWhXYjZM"),
    43  				PayloadRound:     1,
    44  				ProofOfWorkNonce: asHex("df2ea592260c0100"),
    45  				LbVote:           mavryk.FeatureVoteOn,
    46  				AiVote:           mavryk.FeatureVoteOn,
    47  			},
    48  		},
    49  		{
    50  			data: asHex("00000533010e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8000000005e9dcbb00242e9bc4583d4f9fa6ba422733f45d3a44397141a953d2237bf8df62e5046eef700000011000000010100000008000000000000000a4c7319284b55068bb7c4e0b9f8585729db7fb27ab4ca9cff2038a1fc324f650c000000000000000000000000000000000000000000000000000000000000000000000000101895ca00000000ff043691f53c02ca1ac6f1a0c1586bf77973e04c2d9b618a8309e79651daf0d55800"),
    51  			head: BlockHeader{
    52  				Level:          1331,
    53  				Proto:          1,
    54  				Predecessor:    mavryk.MustParseBlockHash("BKpbfCvh777DQHnXjU2sqHvVUNZ7dBAdqEfKkdw8EGSkD9LSYXb"),
    55  				Timestamp:      asTime("2020-04-20T16:20:00Z"),
    56  				ValidationPass: 2,
    57  				OperationsHash: mavryk.MustParseOpListListHash("LLoZqBDX1E2ADRXbmwYo8VtMNeHG6Ygzmm4Zqv97i91UPBQHy9Vq3"),
    58  				Fitness: []mavryk.HexBytes{
    59  					asHex("01"),
    60  					asHex("000000000000000a"),
    61  				},
    62  				Context:          mavryk.MustParseContextHash("CoVDyf9y9gHfAkPWofBJffo4X4bWjmehH2LeVonDcCKKzyQYwqdk"),
    63  				PayloadHash:      mavryk.MustParsePayloadHash("vh1g87ZG6scSYxKhspAUzprQVuLAyoa5qMBKcUfjgnQGnFb3dJcG"),
    64  				PayloadRound:     0,
    65  				ProofOfWorkNonce: asHex("101895ca00000000"),
    66  				SeedNonceHash:    mavryk.MustParseNonceHash("nceUFoeQDgkJCmzdMWh19ZjBYqQD3N9fe6bXQ1ZsUKKvMn7iun5Z3"),
    67  				LbVote:           mavryk.FeatureVoteOn,
    68  				AiVote:           mavryk.FeatureVoteOn,
    69  			},
    70  		},
    71  		{
    72  			data: asHex("0000518e0118425847ac255b6d7c30ce8fec23b8eaf13b741de7d18509ac2ef83c741209630000000061947af504805682ea5d089837764b3efcc90b91db24294ff9ddb66019f332ccba17cc4741000000210000000102000000040000518e0000000000000004ffffffff0000000400000000eb1320a71e8bf8b0162a3ec315461e9153a38b70d00d5dde2df85eb92748f8d068d776e356683a9e23c186ccfb72ddc6c9857bb1704487972922e7c89a7121f800000000a8e1dd3c000000000000"),
    73  			head: BlockHeader{
    74  				Level:          20878,
    75  				Proto:          1,
    76  				Predecessor:    mavryk.MustParseBlockHash("BKty19HXfE15jjeLFCTxpEZRXRVkQKGBcArzn4eAgMYTrdaf6xc"),
    77  				Timestamp:      asTime("2021-11-17T03:45:57Z"),
    78  				ValidationPass: 4,
    79  				OperationsHash: mavryk.MustParseOpListListHash("LLoaJEEVU5t92V3PEFG9SZ6JrgG3AAwLhKXkXxHjfiZFxLZeqaRcg"),
    80  				Fitness: []mavryk.HexBytes{
    81  					asHex("02"),
    82  					asHex("0000518e"),
    83  					asHex(""),
    84  					asHex("ffffffff"),
    85  					asHex("00000000"),
    86  				},
    87  				Context:          mavryk.MustParseContextHash("CoWRqXN1hCqPoLNF5K53DkcqHSHA9638oXnyhg5nBBsK1gNVAQdZ"),
    88  				PayloadHash:      mavryk.MustParsePayloadHash("vh2UJ9qvkLHcFbiotR462Ni84QU7xJ83fNwspoo9kq7spoNeSMkH"),
    89  				PayloadRound:     0,
    90  				ProofOfWorkNonce: asHex("a8e1dd3c00000000"),
    91  				LbVote:           mavryk.FeatureVoteOn,
    92  				AiVote:           mavryk.FeatureVoteOn,
    93  			},
    94  		},
    95  		{
    96  			data:  asHex("0000004c013ce881bd760605e86f07bfd8b462eae0f25151ac056978a9abb392e17cba833f0000000065a3e6f304ebbfbd7dd321a66af71edbb7ae270e4f84d4c50f56a412c53f9efdaaefa11516000000210000000102000000040000004c0000000000000004ffffffff0000000400000000081a1078f1729b2ac0da78480aade344e5f5ccfdcd2035bc59563c1ff80897d05677d1d20902581194154052443de6d0b3c5ffffd62bb8e771e2c1ec62217a25000000007769d51b04000000ff650c5a8c733f89717032992c43ac7f3e121a8dd141184353b5e8c76f25706ea90a"),
    97  			chain: mavryk.MustParseChainIdHash("NetXdQprcVkpaWU"),
    98  			head: BlockHeader{
    99  				Level:          76,
   100  				Proto:          1,
   101  				Predecessor:    mavryk.MustParseBlockHash("BLB79vHaoWiyzYjc68zXWCQFB2snCY28reHR3w6bpvKwZqkZDTE"),
   102  				Timestamp:      asTime("2024-01-14T13:51:47Z"),
   103  				ValidationPass: 4,
   104  				OperationsHash: mavryk.MustParseOpListListHash("LLob7XuR6DGQ2jQPurB7AgBGNFi19WukXyuHd1ncjyXGF13qaAZFc"),
   105  				Fitness: []mavryk.HexBytes{
   106  					asHex("02"),
   107  					asHex("0000004c"),
   108  					asHex(""),
   109  					asHex("ffffffff"),
   110  					asHex("00000000"),
   111  				},
   112  				Context:          mavryk.MustParseContextHash("CoUhsoi3yZqpNGCW1pgu4f7eX2kzbkgKdoekLCny4WtGYyUiH96s"),
   113  				PayloadHash:      mavryk.MustParsePayloadHash("vh2LCpkG49XP71LxG7kVc1ob1erR3FnD3jfHjGJa8caN2N7Jn9nx"),
   114  				PayloadRound:     0,
   115  				ProofOfWorkNonce: asHex("7769d51b04000000"),
   116  				SeedNonceHash:    mavryk.MustParseNonceHash("nceUzTAhmkcBo1CsZhgPKmt9daAaEWcHspXeeHQqSikEMG7dryrMR"),
   117  				LbVote:           mavryk.FeatureVotePass,
   118  				AiVote:           mavryk.FeatureVotePass,
   119  			},
   120  			hash: mavryk.MustParseBlockHash("BKsWjip13q21S4cRDmrPG85pYJePST41BrFFrRskWoPCecd88fJ"),
   121  			key:  mavryk.MustParsePrivateKey("edsk2uqQB9AY4FvioK2YMdfmyMrer5R8mGFyuaLLFfSRo8EoyNdht3"),
   122  			sig:  mavryk.MustParseSignature("sigqKNyR7Xuo8TzuMSKA5HaL9XRVmozGM1brMm2ekUSpj14HCTE9zPszEvE6Vy1WEFHhpc4m1wsff4MGkXJQcNmhbALJa7bt"),
   123  		},
   124  	}
   125  
   126  	for i, c := range cases {
   127  		// binary decode
   128  		var bh BlockHeader
   129  		if err := bh.UnmarshalBinary(c.data); err != nil {
   130  			t.Errorf("Case %d: decode failed: %v", i, err)
   131  		}
   132  
   133  		// json encode
   134  		j2, err := c.head.MarshalJSON()
   135  		if err != nil {
   136  			t.Errorf("Case %d: JSON marshal failed: %v", i, err)
   137  		}
   138  
   139  		// compare json encodings
   140  		j1, err := bh.MarshalJSON()
   141  		if err != nil {
   142  			t.Errorf("Case %d: JSON marshal from decoded block failed: %v", i, err)
   143  		}
   144  
   145  		if !bytes.Equal(j1, j2) {
   146  			t.Errorf("Case %d: JSON mismatch:\n    1: %s\n    2: %s\n", i,
   147  				string(j1), string(j2),
   148  			)
   149  		}
   150  
   151  		// binary encode
   152  		// we're using DefaultParams here, to change use op.WithParams()
   153  		buf := c.head.Bytes()
   154  		if !bytes.Equal(buf, c.data.Bytes()) {
   155  			t.Errorf("Case %d: encode failed:\n    have: %s\n    want: %s\n", i,
   156  				mavryk.HexBytes(buf), c.data,
   157  			)
   158  		}
   159  
   160  		// check sig
   161  		if c.sig.IsValid() && c.key.IsValid() {
   162  			if err := bh.WithChainId(c.chain).Sign(c.key); err != nil {
   163  				t.Errorf("Case %d: JSON marshal failed: %v", i, err)
   164  			}
   165  			if !bh.Signature.Equal(c.sig) {
   166  				t.Errorf("Case %d: signature mismatch:\n    have: %s\n    want: %s\n", i,
   167  					bh.Signature, c.sig,
   168  				)
   169  			}
   170  
   171  			// check hash (needs a valid signature)
   172  			if c.hash.IsValid() {
   173  				if bh.WithChainId(c.chain).Hash() != c.hash {
   174  					t.Errorf("Case %d: hash failed:\n    have: %s\n    want: %s\n", i,
   175  						bh.Hash(), c.hash,
   176  					)
   177  				}
   178  			}
   179  		}
   180  	}
   181  }