github.com/onflow/flow-go@v0.33.17/cmd/util/ledger/migrations/change_contract_code_migration_test.go (about)

     1  package migrations_test
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/onflow/cadence/runtime/common"
     8  	"github.com/rs/zerolog"
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/onflow/flow-go/cmd/util/ledger/migrations"
    12  	"github.com/onflow/flow-go/ledger"
    13  	"github.com/onflow/flow-go/ledger/common/convert"
    14  	"github.com/onflow/flow-go/model/flow"
    15  )
    16  
    17  func newContractPayload(address common.Address, contractName string, contract []byte) *ledger.Payload {
    18  	return ledger.NewPayload(
    19  		convert.RegisterIDToLedgerKey(
    20  			flow.ContractRegisterID(flow.ConvertAddress(address), contractName),
    21  		),
    22  		contract,
    23  	)
    24  }
    25  
    26  func TestChangeContractCodeMigration(t *testing.T) {
    27  	t.Parallel()
    28  
    29  	address1, err := common.HexToAddress("0x1")
    30  	require.NoError(t, err)
    31  
    32  	address2, err := common.HexToAddress("0x2")
    33  	require.NoError(t, err)
    34  
    35  	ctx := context.Background()
    36  
    37  	t.Run("no contracts", func(t *testing.T) {
    38  		t.Parallel()
    39  
    40  		migration := migrations.ChangeContractCodeMigration{}
    41  		log := zerolog.New(zerolog.NewTestWriter(t))
    42  		err := migration.InitMigration(log, nil, 0)
    43  		require.NoError(t, err)
    44  
    45  		_, err = migration.MigrateAccount(ctx, address1,
    46  			[]*ledger.Payload{},
    47  		)
    48  
    49  		require.NoError(t, err)
    50  
    51  		err = migration.Close()
    52  		require.NoError(t, err)
    53  	})
    54  
    55  	t.Run("1 contract - dont migrate", func(t *testing.T) {
    56  		t.Parallel()
    57  
    58  		migration := migrations.ChangeContractCodeMigration{}
    59  		log := zerolog.New(zerolog.NewTestWriter(t))
    60  		err := migration.InitMigration(log, nil, 0)
    61  		require.NoError(t, err)
    62  
    63  		payloads, err := migration.MigrateAccount(ctx, address1,
    64  			[]*ledger.Payload{
    65  				newContractPayload(address1, "A", []byte("A")),
    66  			},
    67  		)
    68  
    69  		require.NoError(t, err)
    70  		require.Len(t, payloads, 1)
    71  		require.Equal(t, []byte("A"), []byte(payloads[0].Value()))
    72  
    73  		err = migration.Close()
    74  		require.NoError(t, err)
    75  	})
    76  
    77  	t.Run("1 contract - migrate", func(t *testing.T) {
    78  		t.Parallel()
    79  
    80  		migration := migrations.ChangeContractCodeMigration{}
    81  		log := zerolog.New(zerolog.NewTestWriter(t))
    82  		err := migration.InitMigration(log, nil, 0)
    83  		require.NoError(t, err)
    84  
    85  		migration.RegisterContractChange(address1, "A", "B")
    86  
    87  		payloads, err := migration.MigrateAccount(ctx, address1,
    88  			[]*ledger.Payload{
    89  				newContractPayload(address1, "A", []byte("A")),
    90  			},
    91  		)
    92  
    93  		require.NoError(t, err)
    94  		require.Len(t, payloads, 1)
    95  		require.Equal(t, []byte("B"), []byte(payloads[0].Value()))
    96  
    97  		err = migration.Close()
    98  		require.NoError(t, err)
    99  	})
   100  
   101  	t.Run("2 contracts - migrate 1", func(t *testing.T) {
   102  		t.Parallel()
   103  
   104  		migration := migrations.ChangeContractCodeMigration{}
   105  		log := zerolog.New(zerolog.NewTestWriter(t))
   106  		err := migration.InitMigration(log, nil, 0)
   107  		require.NoError(t, err)
   108  
   109  		migration.RegisterContractChange(address1, "A", "B")
   110  
   111  		payloads, err := migration.MigrateAccount(ctx, address1,
   112  			[]*ledger.Payload{
   113  				newContractPayload(address1, "A", []byte("A")),
   114  				newContractPayload(address1, "B", []byte("A")),
   115  			},
   116  		)
   117  
   118  		require.NoError(t, err)
   119  		require.Len(t, payloads, 2)
   120  		require.Equal(t, []byte("B"), []byte(payloads[0].Value()))
   121  		require.Equal(t, []byte("A"), []byte(payloads[1].Value()))
   122  
   123  		err = migration.Close()
   124  		require.NoError(t, err)
   125  	})
   126  
   127  	t.Run("2 contracts - migrate 2", func(t *testing.T) {
   128  		t.Parallel()
   129  
   130  		migration := migrations.ChangeContractCodeMigration{}
   131  		log := zerolog.New(zerolog.NewTestWriter(t))
   132  		err := migration.InitMigration(log, nil, 0)
   133  		require.NoError(t, err)
   134  
   135  		migration.RegisterContractChange(address1, "A", "B")
   136  		migration.RegisterContractChange(address1, "B", "B")
   137  
   138  		payloads, err := migration.MigrateAccount(ctx, address1,
   139  			[]*ledger.Payload{
   140  				newContractPayload(address1, "A", []byte("A")),
   141  				newContractPayload(address1, "B", []byte("A")),
   142  			},
   143  		)
   144  
   145  		require.NoError(t, err)
   146  		require.Len(t, payloads, 2)
   147  		require.Equal(t, []byte("B"), []byte(payloads[0].Value()))
   148  		require.Equal(t, []byte("B"), []byte(payloads[1].Value()))
   149  
   150  		err = migration.Close()
   151  		require.NoError(t, err)
   152  	})
   153  
   154  	t.Run("2 contracts on different accounts - migrate 1", func(t *testing.T) {
   155  		t.Parallel()
   156  
   157  		migration := migrations.ChangeContractCodeMigration{}
   158  		log := zerolog.New(zerolog.NewTestWriter(t))
   159  		err := migration.InitMigration(log, nil, 0)
   160  		require.NoError(t, err)
   161  
   162  		migration.RegisterContractChange(address1, "A", "B")
   163  
   164  		payloads, err := migration.MigrateAccount(ctx, address1,
   165  			[]*ledger.Payload{
   166  				newContractPayload(address1, "A", []byte("A")),
   167  				newContractPayload(address2, "A", []byte("A")),
   168  			},
   169  		)
   170  
   171  		require.NoError(t, err)
   172  		require.Len(t, payloads, 2)
   173  		require.Equal(t, []byte("B"), []byte(payloads[0].Value()))
   174  		require.Equal(t, []byte("A"), []byte(payloads[1].Value()))
   175  
   176  		err = migration.Close()
   177  		require.NoError(t, err)
   178  	})
   179  
   180  	t.Run("not all contracts on one account migrated", func(t *testing.T) {
   181  		t.Parallel()
   182  
   183  		migration := migrations.ChangeContractCodeMigration{}
   184  		log := zerolog.New(zerolog.NewTestWriter(t))
   185  		err := migration.InitMigration(log, nil, 0)
   186  		require.NoError(t, err)
   187  
   188  		migration.RegisterContractChange(address1, "A", "B")
   189  		migration.RegisterContractChange(address1, "B", "B")
   190  
   191  		_, err = migration.MigrateAccount(ctx, address1,
   192  			[]*ledger.Payload{
   193  				newContractPayload(address1, "A", []byte("A")),
   194  			},
   195  		)
   196  
   197  		require.Error(t, err)
   198  	})
   199  
   200  	t.Run("not all accounts migrated", func(t *testing.T) {
   201  		t.Parallel()
   202  
   203  		migration := migrations.ChangeContractCodeMigration{}
   204  		log := zerolog.New(zerolog.NewTestWriter(t))
   205  		err := migration.InitMigration(log, nil, 0)
   206  		require.NoError(t, err)
   207  
   208  		migration.RegisterContractChange(address2, "A", "B")
   209  
   210  		_, err = migration.MigrateAccount(ctx, address1,
   211  			[]*ledger.Payload{
   212  				newContractPayload(address1, "A", []byte("A")),
   213  			},
   214  		)
   215  
   216  		require.NoError(t, err)
   217  
   218  		err = migration.Close()
   219  		require.Error(t, err)
   220  	})
   221  }