github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/cmd/util/ledger/migrations/deploy_migration_test.go (about) 1 package migrations 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/rs/zerolog" 8 "github.com/stretchr/testify/require" 9 10 "github.com/onflow/flow-go/cmd/util/ledger/util/registers" 11 "github.com/onflow/flow-go/fvm" 12 "github.com/onflow/flow-go/fvm/storage/snapshot" 13 "github.com/onflow/flow-go/fvm/systemcontracts" 14 "github.com/onflow/flow-go/ledger" 15 "github.com/onflow/flow-go/ledger/common/convert" 16 "github.com/onflow/flow-go/model/flow" 17 "github.com/onflow/flow-go/utils/unittest" 18 ) 19 20 func newBootstrapPayloads( 21 chainID flow.ChainID, 22 bootstrapProcedureOptions ...fvm.BootstrapProcedureOption, 23 ) ([]*ledger.Payload, error) { 24 25 ctx := fvm.NewContext( 26 fvm.WithChain(chainID.Chain()), 27 ) 28 29 vm := fvm.NewVirtualMachine() 30 31 storageSnapshot := snapshot.MapStorageSnapshot{} 32 33 bootstrapProcedure := fvm.Bootstrap( 34 unittest.ServiceAccountPublicKey, 35 bootstrapProcedureOptions..., 36 ) 37 38 executionSnapshot, _, err := vm.Run( 39 ctx, 40 bootstrapProcedure, 41 storageSnapshot, 42 ) 43 if err != nil { 44 return nil, err 45 } 46 47 payloads := make([]*ledger.Payload, 0, len(executionSnapshot.WriteSet)) 48 49 for registerID, registerValue := range executionSnapshot.WriteSet { 50 payloadKey := convert.RegisterIDToLedgerKey(registerID) 51 payload := ledger.NewPayload(payloadKey, registerValue) 52 payloads = append(payloads, payload) 53 } 54 55 return payloads, nil 56 } 57 58 func TestDeploy(t *testing.T) { 59 t.Parallel() 60 61 const chainID = flow.Emulator 62 63 chain := chainID.Chain() 64 65 const nWorker = 2 66 67 systemContracts := systemcontracts.SystemContractsForChain(chainID) 68 serviceAccountAddress := systemContracts.FlowServiceAccount.Address 69 fungibleTokenAddress := systemContracts.FungibleToken.Address 70 71 targetAddress := serviceAccountAddress 72 73 migration := NewDeploymentMigration( 74 chainID, 75 Contract{ 76 Name: "NewContract", 77 Code: []byte(fmt.Sprintf( 78 ` 79 import FungibleToken from %s 80 81 access(all) 82 contract NewContract { 83 84 access(all) 85 fun answer(): Int { 86 return 42 87 } 88 } 89 `, 90 fungibleTokenAddress.HexWithPrefix(), 91 )), 92 }, 93 targetAddress, 94 map[flow.Address]struct{}{ 95 targetAddress: {}, 96 }, 97 zerolog.New(zerolog.NewTestWriter(t)), 98 ) 99 100 bootstrapPayloads, err := newBootstrapPayloads(chainID) 101 require.NoError(t, err) 102 103 filteredPayloads := make([]*ledger.Payload, 0, len(bootstrapPayloads)) 104 105 // TODO: move to NewTransactionBasedMigration 106 107 // Filter the bootstrapped payloads to only include the target account (service account) 108 // and the account where the fungible token is deployed 109 110 for _, payload := range bootstrapPayloads { 111 registerID, _, err := convert.PayloadToRegister(payload) 112 require.NoError(t, err) 113 114 if len(registerID.Owner) > 0 { 115 registerAddress := flow.Address([]byte(registerID.Owner)) 116 switch registerAddress { 117 case targetAddress, fungibleTokenAddress: 118 filteredPayloads = append(filteredPayloads, payload) 119 } 120 } else { 121 filteredPayloads = append(filteredPayloads, payload) 122 } 123 } 124 125 registersByAccount, err := registers.NewByAccountFromPayloads(filteredPayloads) 126 require.NoError(t, err) 127 128 err = migration(registersByAccount) 129 require.NoError(t, err) 130 131 txBody := flow.NewTransactionBody(). 132 SetScript([]byte(fmt.Sprintf( 133 ` 134 import NewContract from %s 135 136 transaction { 137 execute { 138 log(NewContract.answer()) 139 } 140 } 141 `, 142 targetAddress.HexWithPrefix(), 143 ))) 144 145 vm := fvm.NewVirtualMachine() 146 147 storageSnapshot := snapshot.MapStorageSnapshot{} 148 149 newPayloads := registersByAccount.DestructIntoPayloads(nWorker) 150 151 for _, newPayload := range newPayloads { 152 registerID, registerValue, err := convert.PayloadToRegister(newPayload) 153 require.NoError(t, err) 154 155 storageSnapshot[registerID] = registerValue 156 } 157 158 ctx := fvm.NewContext( 159 fvm.WithChain(chain), 160 fvm.WithAuthorizationChecksEnabled(false), 161 fvm.WithSequenceNumberCheckAndIncrementEnabled(false), 162 fvm.WithCadenceLogging(true), 163 ) 164 165 _, output, err := vm.Run( 166 ctx, 167 fvm.Transaction(txBody, 0), 168 storageSnapshot, 169 ) 170 171 require.NoError(t, err) 172 require.NoError(t, output.Err) 173 require.Len(t, output.Logs, 1) 174 require.Equal(t, "42", output.Logs[0]) 175 }