github.com/mavryk-network/mvgo@v1.19.9/codec/op_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  	"encoding/hex"
     9  	"encoding/json"
    10  	"fmt"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/mavryk-network/mvgo/mavryk"
    15  	"github.com/mavryk-network/mvgo/micheline"
    16  )
    17  
    18  func asTime(s string) time.Time {
    19  	t, err := time.Parse(time.RFC3339, s)
    20  	if err != nil {
    21  		panic(fmt.Errorf("Parsing time %q: %v", s, err))
    22  	}
    23  	return t
    24  }
    25  
    26  func asHex(s string) mavryk.HexBytes {
    27  	buf, err := hex.DecodeString(s)
    28  	if err != nil {
    29  		panic(fmt.Errorf("Parsing hex %q: %v", s, err))
    30  	}
    31  	return mavryk.HexBytes(buf)
    32  }
    33  
    34  func asScript(s string) micheline.Script {
    35  	var sc micheline.Script
    36  	if err := json.Unmarshal([]byte(s), &sc); err != nil {
    37  		panic(fmt.Errorf("Parsing script %q: %v", s, err))
    38  	}
    39  	return sc
    40  }
    41  
    42  func asIntPtr(i int64) *mavryk.N {
    43  	n := mavryk.N(i)
    44  	return &n
    45  }
    46  
    47  func TestOp(t *testing.T) {
    48  	type testcase struct {
    49  		name string
    50  		data mavryk.HexBytes
    51  		op   Op
    52  	}
    53  
    54  	var cases = []testcase{
    55  		// Tenderbake preendorsement
    56  		{
    57  			name: "Tenderbake preendorsement",
    58  			data: asHex("2f50673bab6b20dfb0a88ca93b4a0c72a34c807af5dffbece2cba3d2b509835f14006000000002000000041f1ebb39759cc957216f88fb4d005abc206fb00a53f8d57ac01be00c084cba97"),
    59  			op: Op{
    60  				Branch: mavryk.MustParseBlockHash("BL57uk2FrPckCtzBQwaQV1bYtPPShcDCqMShArucaBSpqtmDdRn"),
    61  				Contents: []Operation{
    62  					&TenderbakePreendorsement{
    63  						Slot:             96,
    64  						Level:            2,
    65  						Round:            4,
    66  						BlockPayloadHash: mavryk.MustParsePayloadHash("vh1uq2uMDFaJAZZcydX5QeW2dG3Mpc2y31tT621LuEppkxfy11SK"),
    67  					},
    68  				},
    69  			},
    70  		},
    71  		// Tenderbake endorsement
    72  		{
    73  			name: "Tenderbake endorsement",
    74  			data: asHex("fc81eee810737b04018acef4db74d056b79edc43e6be46cae7e4c217c22a82f01500120000518d0000000003e7ea1f67dbb0bb6cfa372cb092cd9cf786b4f1b5e5139da95b915fb95e698d"),
    75  			op: Op{
    76  				Branch: mavryk.MustParseBlockHash("BMdVJUZrmcLJBnXsxdJLJaTDFJYyqarwmst7hpPu53Z3xLPtnMF"),
    77  				Contents: []Operation{
    78  					&TenderbakeEndorsement{
    79  						Slot:             18,
    80  						Level:            20877,
    81  						Round:            0,
    82  						BlockPayloadHash: mavryk.MustParsePayloadHash("vh1hqtJCryS2Uzb8KDU2PAp33U1nDCeUB4g9yWKTjgVhiy4x9pQA"),
    83  					},
    84  				},
    85  			},
    86  		},
    87  		// Tenderbake double endorsement evidence
    88  		{
    89  			name: "Tenderbake double endorsement evidence",
    90  			data: asHex("fc81eee810737b04018acef4db74d056b79edc43e6be46cae7e4c217c22a82f0020000008ba60703a9567bf69ec66b368c3d8562eba4cbf29278c2c10447a684e3aa1436851500120000518d0000000003e7ea1f67dbb0bb6cfa372cb092cd9cf786b4f1b5e5139da95b915fb95e698dd3a9e1467b32104921d4e2dd93265739c1a5faee7a7f8880842b096c0b6714200c43fd5872f82581dfe1cb3a76ccdadaa4d6361d72b4abee6884cb7ed87f0b040000008ba60703a9567bf69ec66b368c3d8562eba4cbf29278c2c10447a684e3aa1436851500120000518d0000000003e7ea1f67dbb0bb6cfa372cb092cd9cf786b4f1b5e5139da95b915fb95e698dd3a9e1467b32104921d4e2dd93265739c1a5faee7a7f8880842b096c0b6714200c43fd5872f82581dfe1cb3a76ccdadaa4d6361d72b4abee6884cb7ed87f0b04"),
    91  			op: Op{
    92  				Branch: mavryk.MustParseBlockHash("BMdVJUZrmcLJBnXsxdJLJaTDFJYyqarwmst7hpPu53Z3xLPtnMF"),
    93  				Contents: []Operation{
    94  					&TenderbakeDoubleEndorsementEvidence{
    95  						Op1: TenderbakeInlinedEndorsement{
    96  							Branch: mavryk.MustParseBlockHash("BLyQHMFeNzZEKHmKgfD9imcowLm8hc4aUo16QtYZcS5yvx7RFqQ"),
    97  							Endorsement: TenderbakeEndorsement{
    98  								Slot:             18,
    99  								Level:            20877,
   100  								Round:            0,
   101  								BlockPayloadHash: mavryk.MustParsePayloadHash("vh1hqtJCryS2Uzb8KDU2PAp33U1nDCeUB4g9yWKTjgVhiy4x9pQA"),
   102  							},
   103  							Signature: mavryk.MustParseSignature("sigqgQgW5qQCsuHP5HhMhAYR2HjcChUE7zAczsyCdF681rfZXpxnXFHu3E6ycmz4pQahjvu3VLfa7FMCxZXmiMiuZFQS4MHy"),
   104  						},
   105  						Op2: TenderbakeInlinedEndorsement{
   106  							Branch: mavryk.MustParseBlockHash("BLyQHMFeNzZEKHmKgfD9imcowLm8hc4aUo16QtYZcS5yvx7RFqQ"),
   107  							Endorsement: TenderbakeEndorsement{
   108  								Slot:             18,
   109  								Level:            20877,
   110  								Round:            0,
   111  								BlockPayloadHash: mavryk.MustParsePayloadHash("vh1hqtJCryS2Uzb8KDU2PAp33U1nDCeUB4g9yWKTjgVhiy4x9pQA"),
   112  							},
   113  							Signature: mavryk.MustParseSignature("sigqgQgW5qQCsuHP5HhMhAYR2HjcChUE7zAczsyCdF681rfZXpxnXFHu3E6ycmz4pQahjvu3VLfa7FMCxZXmiMiuZFQS4MHy"),
   114  						},
   115  					},
   116  				},
   117  			},
   118  		},
   119  		// Tenderbake double preendorsement evidence
   120  		{
   121  			name: "Tenderbake double preendorsement evidence",
   122  			data: asHex("fc81eee810737b04018acef4db74d056b79edc43e6be46cae7e4c217c22a82f0070000008ba60703a9567bf69ec66b368c3d8562eba4cbf29278c2c10447a684e3aa1436851400120000518d0000000003e7ea1f67dbb0bb6cfa372cb092cd9cf786b4f1b5e5139da95b915fb95e698dd3a9e1467b32104921d4e2dd93265739c1a5faee7a7f8880842b096c0b6714200c43fd5872f82581dfe1cb3a76ccdadaa4d6361d72b4abee6884cb7ed87f0b040000008ba60703a9567bf69ec66b368c3d8562eba4cbf29278c2c10447a684e3aa1436851400120000518d0000000003e7ea1f67dbb0bb6cfa372cb092cd9cf786b4f1b5e5139da95b915fb95e698dd3a9e1467b32104921d4e2dd93265739c1a5faee7a7f8880842b096c0b6714200c43fd5872f82581dfe1cb3a76ccdadaa4d6361d72b4abee6884cb7ed87f0b04"),
   123  			op: Op{
   124  				Branch: mavryk.MustParseBlockHash("BMdVJUZrmcLJBnXsxdJLJaTDFJYyqarwmst7hpPu53Z3xLPtnMF"),
   125  				Contents: []Operation{
   126  					&TenderbakeDoublePreendorsementEvidence{
   127  						Op1: TenderbakeInlinedPreendorsement{
   128  							Branch: mavryk.MustParseBlockHash("BLyQHMFeNzZEKHmKgfD9imcowLm8hc4aUo16QtYZcS5yvx7RFqQ"),
   129  							Endorsement: TenderbakePreendorsement{
   130  								Slot:             18,
   131  								Level:            20877,
   132  								Round:            0,
   133  								BlockPayloadHash: mavryk.MustParsePayloadHash("vh1hqtJCryS2Uzb8KDU2PAp33U1nDCeUB4g9yWKTjgVhiy4x9pQA"),
   134  							},
   135  							Signature: mavryk.MustParseSignature("sigqgQgW5qQCsuHP5HhMhAYR2HjcChUE7zAczsyCdF681rfZXpxnXFHu3E6ycmz4pQahjvu3VLfa7FMCxZXmiMiuZFQS4MHy"),
   136  						},
   137  						Op2: TenderbakeInlinedPreendorsement{
   138  							Branch: mavryk.MustParseBlockHash("BLyQHMFeNzZEKHmKgfD9imcowLm8hc4aUo16QtYZcS5yvx7RFqQ"),
   139  							Endorsement: TenderbakePreendorsement{
   140  								Slot:             18,
   141  								Level:            20877,
   142  								Round:            0,
   143  								BlockPayloadHash: mavryk.MustParsePayloadHash("vh1hqtJCryS2Uzb8KDU2PAp33U1nDCeUB4g9yWKTjgVhiy4x9pQA"),
   144  							},
   145  							Signature: mavryk.MustParseSignature("sigqgQgW5qQCsuHP5HhMhAYR2HjcChUE7zAczsyCdF681rfZXpxnXFHu3E6ycmz4pQahjvu3VLfa7FMCxZXmiMiuZFQS4MHy"),
   146  						},
   147  					},
   148  				},
   149  			},
   150  		},
   151  		// Tenderbake double baking evidence
   152  		{
   153  			name: "Tenderbake double baking evidence",
   154  			data: asHex("fc81eee810737b04018acef4db74d056b79edc43e6be46cae7e4c217c22a82f003000001010004ad5702d21acd0569ff8e03cd564fdc15baae8e436b141510f4ca966bdadfe092904359000000006242e26904cf318e718893b9efb0a426130f6d8fac752db1c47a98d0c3f89780ec8b1a4740000000210000000102000000040004ad570000000000000004ffffffff00000004000000016ae0589f63d96d15d6b41b4e9a9c6f5670ae7e4a3495ffdaf0fa651a10b9e25d9253ed831d88bb031de4f49e43d62977864806a7b0945e8877b030150f2ae63b00000001df2ea592260c01000000517c25c5845f9694eae582055b16ecd9805b318c627d1645f0a4dbf8bf51f4fa51bf5ed45b7e0e1bf64e9fced0ccb96125a22532214d3cbedc745f16b94e0e45000001010004ad5702d21acd0569ff8e03cd564fdc15baae8e436b141510f4ca966bdadfe092904359000000006242e26904cf318e718893b9efb0a426130f6d8fac752db1c47a98d0c3f89780ec8b1a4740000000210000000102000000040004ad570000000000000004ffffffff00000004000000016ae0589f63d96d15d6b41b4e9a9c6f5670ae7e4a3495ffdaf0fa651a10b9e25d9253ed831d88bb031de4f49e43d62977864806a7b0945e8877b030150f2ae63b00000001df2ea592260c01000000c5fa33a8748fe231310655dd03d2543473856ef5beec03bf10030fed2f7d86a7d79c71a3e0a5814da2337865f3bfd307d4b6e7f0e69e9546b341c4109fc342e9"),
   155  			op: Op{
   156  				Branch: mavryk.MustParseBlockHash("BMdVJUZrmcLJBnXsxdJLJaTDFJYyqarwmst7hpPu53Z3xLPtnMF"),
   157  				Contents: []Operation{
   158  					&DoubleBakingEvidence{
   159  						Bh1: BlockHeader{
   160  							Level:          306519,
   161  							Proto:          2,
   162  							Predecessor:    mavryk.MustParseBlockHash("BMJpBGs6rDpEGki8vLVd6VAcLrnEnAhxAwpGjExRcT8qDCmwQQm"),
   163  							Timestamp:      asTime("2022-03-29T10:41:45Z"),
   164  							ValidationPass: 4,
   165  							OperationsHash: mavryk.MustParseOpListListHash("LLoatxVfWnkjHGYBuXL6ELtKqkX1EvLr5ffHSd5pySMY88AY2MeMr"),
   166  							Fitness: []mavryk.HexBytes{
   167  								asHex("02"),
   168  								asHex("0004ad57"),
   169  								asHex(""),
   170  								asHex("ffffffff"),
   171  								asHex("00000001"),
   172  							},
   173  							Context:          mavryk.MustParseContextHash("CoVTNsN2t3DU6m6nL2HL3qEzCA2jhiUEAnWZde7dPmzcdm61EYBp"),
   174  							PayloadHash:      mavryk.MustParsePayloadHash("vh2nZrxixzv4ZjAJn7PRj79GumUMAJzxuEYMjo496TYSaWhXYjZM"),
   175  							PayloadRound:     1,
   176  							ProofOfWorkNonce: asHex("df2ea592260c0100"),
   177  							LbVote:           mavryk.FeatureVoteOn,
   178  							AiVote:           mavryk.FeatureVoteOn,
   179  							Signature:        mavryk.MustParseSignature("sigYec9pbutMj4sxHxGhmQeoU62K96Xbdr8MZJE4XG7PkcKmUGsQMKwpegwdubccUXshdCHukUxDodvaCjpQQaDjagW43YeW"),
   180  						},
   181  						Bh2: BlockHeader{
   182  							Level:          306519,
   183  							Proto:          2,
   184  							Predecessor:    mavryk.MustParseBlockHash("BMJpBGs6rDpEGki8vLVd6VAcLrnEnAhxAwpGjExRcT8qDCmwQQm"),
   185  							Timestamp:      asTime("2022-03-29T10:41:45Z"),
   186  							ValidationPass: 4,
   187  							OperationsHash: mavryk.MustParseOpListListHash("LLoatxVfWnkjHGYBuXL6ELtKqkX1EvLr5ffHSd5pySMY88AY2MeMr"),
   188  							Fitness: []mavryk.HexBytes{
   189  								asHex("02"),
   190  								asHex("0004ad57"),
   191  								asHex(""),
   192  								asHex("ffffffff"),
   193  								asHex("00000001"),
   194  							},
   195  							Context:          mavryk.MustParseContextHash("CoVTNsN2t3DU6m6nL2HL3qEzCA2jhiUEAnWZde7dPmzcdm61EYBp"),
   196  							PayloadHash:      mavryk.MustParsePayloadHash("vh2nZrxixzv4ZjAJn7PRj79GumUMAJzxuEYMjo496TYSaWhXYjZM"),
   197  							PayloadRound:     1,
   198  							ProofOfWorkNonce: asHex("df2ea592260c0100"),
   199  							LbVote:           mavryk.FeatureVoteOn,
   200  							AiVote:           mavryk.FeatureVoteOn,
   201  							Signature:        mavryk.MustParseSignature("sigotZGfNkiFwpditQfPjQ6DpN5QnAo6gjFjAMTdU9ATCcoUyugBtw2p6dqJmvNSETzqN2hTaKJytZJh2abMJ7S49AhX8n13"),
   202  						},
   203  					},
   204  				},
   205  			},
   206  		},
   207  		// seed nonce
   208  		{
   209  			name: "seed nonce",
   210  			data: asHex("2bf383405f10841ea2a1180af0190a8612916c2d12c01dbcf25c415ded192105010004e000fcf77031019bf38c6edd3e360154b6160258df5b21e158f79a03576d67a284f7"),
   211  			op: Op{
   212  				Branch: mavryk.MustParseBlockHash("BL3e1ZpSS6s65BMZDkGnP7kVFuCAA5qfVeSnUmQiDn9NFKGDgNd"),
   213  				Contents: []Operation{
   214  					&SeedNonceRevelation{
   215  						Level: 319488,
   216  						Nonce: asHex("fcf77031019bf38c6edd3e360154b6160258df5b21e158f79a03576d67a284f7"),
   217  					},
   218  				},
   219  			},
   220  		},
   221  
   222  		// proposal
   223  		{
   224  			name: "proposal",
   225  			data: asHex("2bf383405f10841ea2a1180af0190a8612916c2d12c01dbcf25c415ded19210505002cca28ad0529681a2cc52e360ff1b4c1d67d7e600000000f00000020ce5f061e34b5a21feab8dbdfe755ef17e70c9f565464f067ac5e7c02be830a48"),
   226  			op: Op{
   227  				Branch: mavryk.MustParseBlockHash("BL3e1ZpSS6s65BMZDkGnP7kVFuCAA5qfVeSnUmQiDn9NFKGDgNd"),
   228  				Contents: []Operation{
   229  					&Proposals{
   230  						Source: mavryk.MustParseAddress("mv1C6KuPzs92LTENfXUPXq1oNxvaLjxJ9p8b"),
   231  						Period: 15,
   232  						Proposals: []mavryk.ProtocolHash{
   233  							mavryk.MustParseProtocolHash("PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx"),
   234  						},
   235  					},
   236  				},
   237  			},
   238  		},
   239  
   240  		// ballot
   241  		{
   242  			name: "ballot",
   243  			data: asHex("2bf383405f10841ea2a1180af0190a8612916c2d12c01dbcf25c415ded19210506002cca28ad0529681a2cc52e360ff1b4c1d67d7e600000000fce5f061e34b5a21feab8dbdfe755ef17e70c9f565464f067ac5e7c02be830a4800"),
   244  			op: Op{
   245  				Branch: mavryk.MustParseBlockHash("BL3e1ZpSS6s65BMZDkGnP7kVFuCAA5qfVeSnUmQiDn9NFKGDgNd"),
   246  				Contents: []Operation{
   247  					&Ballot{
   248  						Source:   mavryk.MustParseAddress("mv1C6KuPzs92LTENfXUPXq1oNxvaLjxJ9p8b"),
   249  						Period:   15,
   250  						Proposal: mavryk.MustParseProtocolHash("PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx"),
   251  						Ballot:   mavryk.BallotVoteYay,
   252  					},
   253  				},
   254  			},
   255  		},
   256  
   257  		// activate
   258  		{
   259  			name: "activate",
   260  			data: asHex("2bf383405f10841ea2a1180af0190a8612916c2d12c01dbcf25c415ded19210504c118171a1334d71e988f7cc63f0e2d0e3d025c622cd088062ac8665178c8379fac2d4ac52b9357a3"),
   261  			op: Op{
   262  				Branch: mavryk.MustParseBlockHash("BL3e1ZpSS6s65BMZDkGnP7kVFuCAA5qfVeSnUmQiDn9NFKGDgNd"),
   263  				Contents: []Operation{
   264  					&ActivateAccount{
   265  						PublicKeyHash: mavryk.MustParseAddress("mv1RcVGZ46tRpYh2pnkSPiQA7r72LRpQpBUE"),
   266  						Secret:        asHex("2cd088062ac8665178c8379fac2d4ac52b9357a3"),
   267  					},
   268  				},
   269  			},
   270  		},
   271  		// reveal
   272  		{
   273  			name: "reveal",
   274  			data: asHex("09af86395fee09cfbede6b11339cd53216aeee93c38b9bf5cee4c791b814df8c6b005c7886828ec2a24f1814484de7dd53e559831c3fe807c197b001e8070000654b5b22880736d33865b4f30367e90feb81b17cc0ceb7ac951a0066142d5847"),
   275  			op: Op{
   276  				Branch: mavryk.MustParseBlockHash("BKnYk1T5a49bb8me4WfQeugyFnMEH9h8cm6jqvL3BxRwE23EVBJ"),
   277  				Contents: []Operation{
   278  					&Reveal{
   279  						Manager: Manager{
   280  							Source:       mavryk.MustParseAddress("mv1GSSYcW7vUGkoXRpbj8nrXYjWyar1pyDpt"),
   281  							Fee:          1000,
   282  							Counter:      2886593,
   283  							GasLimit:     1000,
   284  							StorageLimit: 0,
   285  						},
   286  						PublicKey: mavryk.MustParseKey("edpkuQqN9HB3jY1FvDzt15WQDVSHR4vQGd1wv6iqJ73wkrKecRtnXh"),
   287  					},
   288  				},
   289  			},
   290  		},
   291  
   292  		// transaction
   293  		{
   294  			name: "transaction",
   295  			data: asHex("09af86395fee09cfbede6b11339cd53216aeee93c38b9bf5cee4c791b814df8c6c005c7886828ec2a24f1814484de7dd53e559831c3fe807c297b0018c0b00c0843d00002cca28ad0529681a2cc52e360ff1b4c1d67d7e6000"),
   296  			op: Op{
   297  				Branch: mavryk.MustParseBlockHash("BKnYk1T5a49bb8me4WfQeugyFnMEH9h8cm6jqvL3BxRwE23EVBJ"),
   298  				Contents: []Operation{
   299  					&Transaction{
   300  						Manager: Manager{
   301  							Source:       mavryk.MustParseAddress("mv1GSSYcW7vUGkoXRpbj8nrXYjWyar1pyDpt"),
   302  							Fee:          1000,
   303  							Counter:      2886594,
   304  							GasLimit:     1420,
   305  							StorageLimit: 0,
   306  						},
   307  						Destination: mavryk.MustParseAddress("mv1C6KuPzs92LTENfXUPXq1oNxvaLjxJ9p8b"),
   308  						Amount:      1000000,
   309  					},
   310  				},
   311  			},
   312  		},
   313  
   314  		// origination
   315  		{
   316  			name: "origination",
   317  			data: asHex("09af86395fee09cfbede6b11339cd53216aeee93c38b9bf5cee4c791b814df8c6d005c7886828ec2a24f1814484de7dd53e559831c3fef0ac297b0018157c30280c2d72f000000001c02000000170500036805010368050202000000080316053d036d03420000000a010000000568656c6c6f"),
   318  			op: Op{
   319  				Branch: mavryk.MustParseBlockHash("BKnYk1T5a49bb8me4WfQeugyFnMEH9h8cm6jqvL3BxRwE23EVBJ"),
   320  				Contents: []Operation{
   321  					&Origination{
   322  						Manager: Manager{
   323  							Source:       mavryk.MustParseAddress("mv1GSSYcW7vUGkoXRpbj8nrXYjWyar1pyDpt"),
   324  							Fee:          1391,
   325  							Counter:      2886594,
   326  							GasLimit:     11137,
   327  							StorageLimit: 323,
   328  						},
   329  						Balance: 100000000,
   330  						Script:  asScript(`{"code": [{"args": [{"prim": "string"}],"prim": "parameter"},{"args": [{"prim": "string"}],"prim": "storage"},{"args": [[{"prim": "CAR"},{"args": [{"prim": "operation"}],"prim": "NIL"},{"prim": "PAIR"}]],"prim": "code"}],"storage": {"string": "hello"}}`),
   331  					},
   332  				},
   333  			},
   334  		},
   335  
   336  		// delegation
   337  		{
   338  			name: "delegation",
   339  			data: asHex("09af86395fee09cfbede6b11339cd53216aeee93c38b9bf5cee4c791b814df8c6e005c7886828ec2a24f1814484de7dd53e559831c3fe807c297b001e80700ff002cca28ad0529681a2cc52e360ff1b4c1d67d7e60"),
   340  			op: Op{
   341  				Branch: mavryk.MustParseBlockHash("BKnYk1T5a49bb8me4WfQeugyFnMEH9h8cm6jqvL3BxRwE23EVBJ"),
   342  				Contents: []Operation{
   343  					&Delegation{
   344  						Manager: Manager{
   345  							Source:       mavryk.MustParseAddress("mv1GSSYcW7vUGkoXRpbj8nrXYjWyar1pyDpt"),
   346  							Fee:          1000,
   347  							Counter:      2886594,
   348  							GasLimit:     1000,
   349  							StorageLimit: 0,
   350  						},
   351  						Delegate: mavryk.MustParseAddress("mv1C6KuPzs92LTENfXUPXq1oNxvaLjxJ9p8b"),
   352  					},
   353  				},
   354  			},
   355  		},
   356  
   357  		// delegation withdraw
   358  		{
   359  			name: "delegation withdraw",
   360  			data: asHex("09af86395fee09cfbede6b11339cd53216aeee93c38b9bf5cee4c791b814df8c6e005c7886828ec2a24f1814484de7dd53e559831c3fe807c297b001e8070000"),
   361  			op: Op{
   362  				Branch: mavryk.MustParseBlockHash("BKnYk1T5a49bb8me4WfQeugyFnMEH9h8cm6jqvL3BxRwE23EVBJ"),
   363  				Contents: []Operation{
   364  					&Delegation{
   365  						Manager: Manager{
   366  							Source:       mavryk.MustParseAddress("mv1GSSYcW7vUGkoXRpbj8nrXYjWyar1pyDpt"),
   367  							Fee:          1000,
   368  							Counter:      2886594,
   369  							GasLimit:     1000,
   370  							StorageLimit: 0,
   371  						},
   372  					},
   373  				},
   374  			},
   375  		},
   376  
   377  		// delegation baker registration
   378  		{
   379  			name: "delegation baker registration",
   380  			data: asHex("09af86395fee09cfbede6b11339cd53216aeee93c38b9bf5cee4c791b814df8c6e005c7886828ec2a24f1814484de7dd53e559831c3fe807c297b001e80700ff005c7886828ec2a24f1814484de7dd53e559831c3f"),
   381  			op: Op{
   382  				Branch: mavryk.MustParseBlockHash("BKnYk1T5a49bb8me4WfQeugyFnMEH9h8cm6jqvL3BxRwE23EVBJ"),
   383  				Contents: []Operation{
   384  					&Delegation{
   385  						Manager: Manager{
   386  							Source:       mavryk.MustParseAddress("mv1GSSYcW7vUGkoXRpbj8nrXYjWyar1pyDpt"),
   387  							Fee:          1000,
   388  							Counter:      2886594,
   389  							GasLimit:     1000,
   390  							StorageLimit: 0,
   391  						},
   392  						Delegate: mavryk.MustParseAddress("mv1GSSYcW7vUGkoXRpbj8nrXYjWyar1pyDpt"),
   393  					},
   394  				},
   395  			},
   396  		},
   397  
   398  		// global constant
   399  		{
   400  			name: "global constant",
   401  			data: asHex("09af86395fee09cfbede6b11339cd53216aeee93c38b9bf5cee4c791b814df8c6f005c7886828ec2a24f1814484de7dd53e559831c3fe807c297b001a08d066400000011010000000c68656c6c6f20776f726c6421"),
   402  			op: Op{
   403  				Branch: mavryk.MustParseBlockHash("BKnYk1T5a49bb8me4WfQeugyFnMEH9h8cm6jqvL3BxRwE23EVBJ"),
   404  				Contents: []Operation{
   405  					&RegisterGlobalConstant{
   406  						Manager: Manager{
   407  							Source:       mavryk.MustParseAddress("mv1GSSYcW7vUGkoXRpbj8nrXYjWyar1pyDpt"),
   408  							Fee:          1000,
   409  							Counter:      2886594,
   410  							GasLimit:     100000,
   411  							StorageLimit: 100,
   412  						},
   413  						Value: micheline.NewString("hello world!"),
   414  					},
   415  				},
   416  			},
   417  		},
   418  
   419  		// set deposits limit
   420  		{
   421  			name: "set deposits limit",
   422  			data: asHex("09af86395fee09cfbede6b11339cd53216aeee93c38b9bf5cee4c791b814df8c70005c7886828ec2a24f1814484de7dd53e559831c3fe807c297b001a08d0664ff64"),
   423  			op: Op{
   424  				Branch: mavryk.MustParseBlockHash("BKnYk1T5a49bb8me4WfQeugyFnMEH9h8cm6jqvL3BxRwE23EVBJ"),
   425  				Contents: []Operation{
   426  					&SetDepositsLimit{
   427  						Manager: Manager{
   428  							Source:       mavryk.MustParseAddress("mv1GSSYcW7vUGkoXRpbj8nrXYjWyar1pyDpt"),
   429  							Fee:          1000,
   430  							Counter:      2886594,
   431  							GasLimit:     100000,
   432  							StorageLimit: 100,
   433  						},
   434  						Limit: asIntPtr(100),
   435  					},
   436  				},
   437  			},
   438  		},
   439  
   440  		// clear deposits limit
   441  		{
   442  			name: "clear deposits limit",
   443  			data: asHex("09af86395fee09cfbede6b11339cd53216aeee93c38b9bf5cee4c791b814df8c70005c7886828ec2a24f1814484de7dd53e559831c3fe807c297b001a08d066400"),
   444  			op: Op{
   445  				Branch: mavryk.MustParseBlockHash("BKnYk1T5a49bb8me4WfQeugyFnMEH9h8cm6jqvL3BxRwE23EVBJ"),
   446  				Contents: []Operation{
   447  					&SetDepositsLimit{
   448  						Manager: Manager{
   449  							Source:       mavryk.MustParseAddress("mv1GSSYcW7vUGkoXRpbj8nrXYjWyar1pyDpt"),
   450  							Fee:          1000,
   451  							Counter:      2886594,
   452  							GasLimit:     100000,
   453  							StorageLimit: 100,
   454  						},
   455  					},
   456  				},
   457  			},
   458  		},
   459  
   460  		// failing noop
   461  		{
   462  			name: "failing noop",
   463  			data: asHex("09af86395fee09cfbede6b11339cd53216aeee93c38b9bf5cee4c791b814df8c110000000c48656c6c6f20576f726c6421"),
   464  			op: Op{
   465  				Branch: mavryk.MustParseBlockHash("BKnYk1T5a49bb8me4WfQeugyFnMEH9h8cm6jqvL3BxRwE23EVBJ"),
   466  				Contents: []Operation{
   467  					&FailingNoop{
   468  						Arbitrary: "Hello World!",
   469  					},
   470  				},
   471  			},
   472  		},
   473  
   474  		// transfer_ticket
   475  		{
   476  			name: "transfer_ticket",
   477  			data: asHex("09af86395fee09cfbede6b11339cd53216aeee93c38b9bf5cee4c791b814df8c9e00fdf904a319c1fb0f073cd2ebc7c0ab71466a1781c306f5b30f82225600000012010000000d74686972642d6465706f736974000000020368013f4a259911e55e00ad15e1b23cacc020dd853bcc0001013f4a259911e55e00ad15e1b23cacc020dd853bcc0000000003787878"),
   478  			op: Op{
   479  				Branch: mavryk.MustParseBlockHash("BKnYk1T5a49bb8me4WfQeugyFnMEH9h8cm6jqvL3BxRwE23EVBJ"),
   480  				Contents: []Operation{
   481  					&TransferTicket{
   482  						Manager: Manager{
   483  							Source:       mavryk.MustParseAddress("mv1XAPGKrKd4CRRHjTgDFLP1GEok7qXGVnvA"),
   484  							Fee:          835,
   485  							Counter:      252405,
   486  							GasLimit:     4354,
   487  							StorageLimit: 86,
   488  						},
   489  						Contents:    micheline.NewString("third-deposit"),
   490  						Type:        micheline.NewPrim(micheline.T_STRING),
   491  						Ticketer:    mavryk.MustParseAddress("KT1EMQxfYVvhTJTqMiVs2ho2dqjbYfYKk6BY"),
   492  						Amount:      mavryk.NewN(1),
   493  						Destination: mavryk.MustParseAddress("KT1EMQxfYVvhTJTqMiVs2ho2dqjbYfYKk6BY"),
   494  						Entrypoint:  "xxx",
   495  					},
   496  				},
   497  			},
   498  		},
   499  	}
   500  
   501  	for _, c := range cases {
   502  		// binary decode
   503  		o, err := DecodeOp(c.data)
   504  		if err != nil {
   505  			t.Errorf("%q: decode failed: %v", c.name, err)
   506  		}
   507  
   508  		// json encode
   509  		j2, err := c.op.MarshalJSON()
   510  		if err != nil {
   511  			t.Errorf("%q: JSON marshal failed: %v", c.name, err)
   512  		}
   513  
   514  		// compare json encodings
   515  		if o != nil {
   516  			j1, err := o.MarshalJSON()
   517  			if err != nil {
   518  				t.Errorf("%q: JSON marshal from decoded op failed: %v", c.name, err)
   519  			}
   520  
   521  			if !bytes.Equal(j1, j2) {
   522  				t.Errorf("%q: JSON mismatch:\n    1: %s\n    2: %s\n", c.name,
   523  					string(j1), string(j2),
   524  				)
   525  			}
   526  		}
   527  
   528  		// binary encode
   529  		// we're using DefaultParams here, to change use op.WithParams()
   530  		buf := c.op.Bytes()
   531  		if !bytes.Equal(buf, c.data.Bytes()) {
   532  			t.Errorf("%q: encode failed:\n    have: %s\n    want: %s\n", c.name,
   533  				mavryk.HexBytes(buf), c.data,
   534  			)
   535  		}
   536  	}
   537  }