github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/core/native/management_test.go (about) 1 package native 2 3 import ( 4 "testing" 5 6 "github.com/nspcc-dev/neo-go/pkg/core/dao" 7 "github.com/nspcc-dev/neo-go/pkg/core/interop" 8 "github.com/nspcc-dev/neo-go/pkg/core/state" 9 "github.com/nspcc-dev/neo-go/pkg/core/storage" 10 "github.com/nspcc-dev/neo-go/pkg/smartcontract" 11 "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" 12 "github.com/nspcc-dev/neo-go/pkg/smartcontract/nef" 13 "github.com/nspcc-dev/neo-go/pkg/util" 14 "github.com/nspcc-dev/neo-go/pkg/vm/opcode" 15 "github.com/stretchr/testify/require" 16 ) 17 18 func TestDeployGetUpdateDestroyContract(t *testing.T) { 19 mgmt := newManagement() 20 mgmt.Policy = newPolicy(false) 21 d := dao.NewSimple(storage.NewMemoryStore(), false) 22 ic := &interop.Context{DAO: d} 23 err := mgmt.Initialize(ic, nil, nil) 24 require.NoError(t, err) 25 require.NoError(t, mgmt.Policy.Initialize(&interop.Context{DAO: d}, nil, nil)) 26 script := []byte{byte(opcode.RET)} 27 sender := util.Uint160{1, 2, 3} 28 ne, err := nef.NewFile(script) 29 require.NoError(t, err) 30 manif := manifest.NewManifest("Test") 31 manif.ABI.Methods = append(manif.ABI.Methods, manifest.Method{ 32 Name: "dummy", 33 ReturnType: smartcontract.VoidType, 34 Parameters: []manifest.Parameter{}, 35 }) 36 37 h := state.CreateContractHash(sender, ne.Checksum, manif.Name) 38 39 contract, err := mgmt.Deploy(ic, sender, ne, manif) 40 require.NoError(t, err) 41 require.Equal(t, int32(1), contract.ID) 42 require.Equal(t, uint16(0), contract.UpdateCounter) 43 require.Equal(t, h, contract.Hash) 44 require.Equal(t, ne, &contract.NEF) 45 require.Equal(t, *manif, contract.Manifest) 46 47 // Double deploy. 48 _, err = mgmt.Deploy(ic, sender, ne, manif) 49 require.Error(t, err) 50 51 // Different sender. 52 sender2 := util.Uint160{3, 2, 1} 53 contract2, err := mgmt.Deploy(ic, sender2, ne, manif) 54 require.NoError(t, err) 55 require.Equal(t, int32(2), contract2.ID) 56 require.Equal(t, uint16(0), contract2.UpdateCounter) 57 require.Equal(t, state.CreateContractHash(sender2, ne.Checksum, manif.Name), contract2.Hash) 58 require.Equal(t, ne, &contract2.NEF) 59 require.Equal(t, *manif, contract2.Manifest) 60 61 refContract, err := GetContract(d, h) 62 require.NoError(t, err) 63 require.Equal(t, contract, refContract) 64 65 refContract, err = GetContractByID(d, contract.ID) 66 require.NoError(t, err) 67 require.Equal(t, contract, refContract) 68 69 upContract, err := mgmt.Update(ic, h, ne, manif) 70 refContract.UpdateCounter++ 71 require.NoError(t, err) 72 require.Equal(t, refContract, upContract) 73 74 err = mgmt.Destroy(d, h) 75 require.NoError(t, err) 76 _, err = GetContract(d, h) 77 require.Error(t, err) 78 _, err = GetContractByID(d, contract.ID) 79 require.Error(t, err) 80 } 81 82 func TestManagement_Initialize(t *testing.T) { 83 t.Run("good", func(t *testing.T) { 84 d := dao.NewSimple(storage.NewMemoryStore(), false) 85 mgmt := newManagement() 86 require.NoError(t, mgmt.InitializeCache(0, d)) 87 }) 88 t.Run("invalid contract state", func(t *testing.T) { 89 d := dao.NewSimple(storage.NewMemoryStore(), false) 90 mgmt := newManagement() 91 d.PutStorageItem(mgmt.ID, []byte{PrefixContract}, state.StorageItem{0xFF}) 92 require.Error(t, mgmt.InitializeCache(0, d)) 93 }) 94 } 95 96 func TestManagement_GetNEP17Contracts(t *testing.T) { 97 mgmt := newManagement() 98 mgmt.Policy = newPolicy(false) 99 d := dao.NewSimple(storage.NewMemoryStore(), false) 100 err := mgmt.Initialize(&interop.Context{DAO: d}, nil, nil) 101 require.NoError(t, err) 102 require.NoError(t, mgmt.Policy.Initialize(&interop.Context{DAO: d}, nil, nil)) 103 err = mgmt.InitializeCache(0, d) 104 require.NoError(t, err) 105 106 require.Empty(t, mgmt.GetNEP17Contracts(d)) 107 private := d.GetPrivate() 108 ic := &interop.Context{DAO: private} 109 110 // Deploy NEP-17 contract 111 script := []byte{byte(opcode.RET)} 112 sender := util.Uint160{1, 2, 3} 113 ne, err := nef.NewFile(script) 114 require.NoError(t, err) 115 manif := manifest.NewManifest("Test") 116 manif.ABI.Methods = append(manif.ABI.Methods, manifest.Method{ 117 Name: "dummy", 118 ReturnType: smartcontract.VoidType, 119 Parameters: []manifest.Parameter{}, 120 }) 121 manif.SupportedStandards = []string{manifest.NEP17StandardName} 122 c1, err := mgmt.Deploy(ic, sender, ne, manif) 123 require.NoError(t, err) 124 125 // c1 contract hash should be returned, as private DAO already contains changed cache. 126 require.Equal(t, []util.Uint160{c1.Hash}, mgmt.GetNEP17Contracts(private)) 127 128 // Lower DAO still shouldn't contain c1, as no Persist was called. 129 require.Empty(t, mgmt.GetNEP17Contracts(d)) 130 131 // Call Persist, check c1 contract hash is returned 132 _, err = private.Persist() 133 require.NoError(t, err) 134 require.Equal(t, []util.Uint160{c1.Hash}, mgmt.GetNEP17Contracts(d)) 135 136 // Update contract 137 private = d.GetPrivate() 138 manif.ABI.Methods = append(manif.ABI.Methods, manifest.Method{ 139 Name: "dummy2", 140 ReturnType: smartcontract.VoidType, 141 Parameters: []manifest.Parameter{}, 142 }) 143 c1Updated, err := mgmt.Update(&interop.Context{DAO: private}, c1.Hash, ne, manif) 144 require.NoError(t, err) 145 require.Equal(t, c1.Hash, c1Updated.Hash) 146 147 // No changes expected in lower store. 148 require.Equal(t, []util.Uint160{c1.Hash}, mgmt.GetNEP17Contracts(d)) 149 c1Lower, err := GetContract(d, c1.Hash) 150 require.NoError(t, err) 151 require.Equal(t, 1, len(c1Lower.Manifest.ABI.Methods)) 152 require.Equal(t, []util.Uint160{c1Updated.Hash}, mgmt.GetNEP17Contracts(private)) 153 c1Upper, err := GetContract(private, c1Updated.Hash) 154 require.NoError(t, err) 155 require.Equal(t, 2, len(c1Upper.Manifest.ABI.Methods)) 156 157 // Call Persist, check c1Updated state is returned from lower. 158 _, err = private.Persist() 159 require.NoError(t, err) 160 require.Equal(t, []util.Uint160{c1.Hash}, mgmt.GetNEP17Contracts(d)) 161 c1Lower, err = GetContract(d, c1.Hash) 162 require.NoError(t, err) 163 require.Equal(t, 2, len(c1Lower.Manifest.ABI.Methods)) 164 }