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  }