2020-12-13 15:26:35 +00:00
|
|
|
package native
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
2021-02-02 15:46:43 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
2020-12-13 15:26:35 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
2021-02-08 10:15:10 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
2020-12-13 15:26:35 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
2021-02-09 18:42:39 +00:00
|
|
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
2020-12-13 15:26:35 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestDeployGetUpdateDestroyContract(t *testing.T) {
|
|
|
|
mgmt := newManagement()
|
2023-09-21 15:22:32 +00:00
|
|
|
mgmt.Policy = newPolicy(false)
|
2023-09-04 13:48:16 +00:00
|
|
|
d := dao.NewSimple(storage.NewMemoryStore(), false)
|
2023-08-03 16:48:55 +00:00
|
|
|
ic := &interop.Context{DAO: d}
|
2024-03-27 17:48:14 +00:00
|
|
|
err := mgmt.Initialize(ic, nil)
|
2021-05-12 18:34:07 +00:00
|
|
|
require.NoError(t, err)
|
2024-03-27 17:48:14 +00:00
|
|
|
require.NoError(t, mgmt.Policy.Initialize(&interop.Context{DAO: d}, nil))
|
2021-02-09 18:42:39 +00:00
|
|
|
script := []byte{byte(opcode.RET)}
|
2020-12-13 15:26:35 +00:00
|
|
|
sender := util.Uint160{1, 2, 3}
|
|
|
|
ne, err := nef.NewFile(script)
|
|
|
|
require.NoError(t, err)
|
|
|
|
manif := manifest.NewManifest("Test")
|
2021-02-08 10:15:10 +00:00
|
|
|
manif.ABI.Methods = append(manif.ABI.Methods, manifest.Method{
|
|
|
|
Name: "dummy",
|
|
|
|
ReturnType: smartcontract.VoidType,
|
|
|
|
Parameters: []manifest.Parameter{},
|
|
|
|
})
|
2020-12-13 15:26:35 +00:00
|
|
|
|
2021-01-22 09:22:48 +00:00
|
|
|
h := state.CreateContractHash(sender, ne.Checksum, manif.Name)
|
|
|
|
|
2023-08-03 16:48:55 +00:00
|
|
|
contract, err := mgmt.Deploy(ic, sender, ne, manif)
|
2020-12-13 15:26:35 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, int32(1), contract.ID)
|
|
|
|
require.Equal(t, uint16(0), contract.UpdateCounter)
|
|
|
|
require.Equal(t, h, contract.Hash)
|
2021-01-13 12:34:10 +00:00
|
|
|
require.Equal(t, ne, &contract.NEF)
|
2020-12-13 15:26:35 +00:00
|
|
|
require.Equal(t, *manif, contract.Manifest)
|
|
|
|
|
|
|
|
// Double deploy.
|
2023-08-03 16:48:55 +00:00
|
|
|
_, err = mgmt.Deploy(ic, sender, ne, manif)
|
2020-12-13 15:26:35 +00:00
|
|
|
require.Error(t, err)
|
|
|
|
|
|
|
|
// Different sender.
|
|
|
|
sender2 := util.Uint160{3, 2, 1}
|
2023-08-03 16:48:55 +00:00
|
|
|
contract2, err := mgmt.Deploy(ic, sender2, ne, manif)
|
2020-12-13 15:26:35 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, int32(2), contract2.ID)
|
|
|
|
require.Equal(t, uint16(0), contract2.UpdateCounter)
|
2021-01-22 09:22:48 +00:00
|
|
|
require.Equal(t, state.CreateContractHash(sender2, ne.Checksum, manif.Name), contract2.Hash)
|
2021-01-13 12:34:10 +00:00
|
|
|
require.Equal(t, ne, &contract2.NEF)
|
2020-12-13 15:26:35 +00:00
|
|
|
require.Equal(t, *manif, contract2.Manifest)
|
|
|
|
|
2022-09-19 19:56:33 +00:00
|
|
|
refContract, err := GetContract(d, h)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, contract, refContract)
|
|
|
|
|
|
|
|
refContract, err = GetContractByID(d, contract.ID)
|
2020-12-13 15:26:35 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, contract, refContract)
|
|
|
|
|
2023-08-03 16:48:55 +00:00
|
|
|
upContract, err := mgmt.Update(ic, h, ne, manif)
|
2020-12-13 15:26:35 +00:00
|
|
|
refContract.UpdateCounter++
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, refContract, upContract)
|
|
|
|
|
|
|
|
err = mgmt.Destroy(d, h)
|
|
|
|
require.NoError(t, err)
|
2022-09-19 19:56:33 +00:00
|
|
|
_, err = GetContract(d, h)
|
|
|
|
require.Error(t, err)
|
|
|
|
_, err = GetContractByID(d, contract.ID)
|
2020-12-13 15:26:35 +00:00
|
|
|
require.Error(t, err)
|
|
|
|
}
|
2020-12-15 10:53:35 +00:00
|
|
|
|
|
|
|
func TestManagement_Initialize(t *testing.T) {
|
|
|
|
t.Run("good", func(t *testing.T) {
|
2023-09-04 13:48:16 +00:00
|
|
|
d := dao.NewSimple(storage.NewMemoryStore(), false)
|
2020-12-15 10:53:35 +00:00
|
|
|
mgmt := newManagement()
|
2023-04-26 09:52:59 +00:00
|
|
|
require.NoError(t, mgmt.InitializeCache(0, d))
|
2020-12-15 10:53:35 +00:00
|
|
|
})
|
|
|
|
t.Run("invalid contract state", func(t *testing.T) {
|
2023-09-04 13:48:16 +00:00
|
|
|
d := dao.NewSimple(storage.NewMemoryStore(), false)
|
2020-12-15 10:53:35 +00:00
|
|
|
mgmt := newManagement()
|
2022-10-20 10:59:19 +00:00
|
|
|
d.PutStorageItem(mgmt.ID, []byte{PrefixContract}, state.StorageItem{0xFF})
|
2023-11-22 11:12:55 +00:00
|
|
|
require.Error(t, mgmt.InitializeCache(0, d))
|
2020-12-15 10:53:35 +00:00
|
|
|
})
|
|
|
|
}
|
2021-07-23 12:52:30 +00:00
|
|
|
|
|
|
|
func TestManagement_GetNEP17Contracts(t *testing.T) {
|
|
|
|
mgmt := newManagement()
|
2023-09-21 15:22:32 +00:00
|
|
|
mgmt.Policy = newPolicy(false)
|
2023-09-04 13:48:16 +00:00
|
|
|
d := dao.NewSimple(storage.NewMemoryStore(), false)
|
2024-03-27 17:48:14 +00:00
|
|
|
err := mgmt.Initialize(&interop.Context{DAO: d}, nil)
|
2021-07-23 12:52:30 +00:00
|
|
|
require.NoError(t, err)
|
2024-03-27 17:48:14 +00:00
|
|
|
require.NoError(t, mgmt.Policy.Initialize(&interop.Context{DAO: d}, nil))
|
2023-04-26 09:52:59 +00:00
|
|
|
err = mgmt.InitializeCache(0, d)
|
2022-04-12 14:29:11 +00:00
|
|
|
require.NoError(t, err)
|
2021-07-23 12:52:30 +00:00
|
|
|
|
2022-04-12 14:29:11 +00:00
|
|
|
require.Empty(t, mgmt.GetNEP17Contracts(d))
|
2022-04-19 14:12:03 +00:00
|
|
|
private := d.GetPrivate()
|
2023-08-03 16:48:55 +00:00
|
|
|
ic := &interop.Context{DAO: private}
|
2021-07-23 12:52:30 +00:00
|
|
|
|
2021-11-18 13:37:42 +00:00
|
|
|
// Deploy NEP-17 contract
|
2021-07-23 12:52:30 +00:00
|
|
|
script := []byte{byte(opcode.RET)}
|
|
|
|
sender := util.Uint160{1, 2, 3}
|
|
|
|
ne, err := nef.NewFile(script)
|
|
|
|
require.NoError(t, err)
|
|
|
|
manif := manifest.NewManifest("Test")
|
|
|
|
manif.ABI.Methods = append(manif.ABI.Methods, manifest.Method{
|
|
|
|
Name: "dummy",
|
|
|
|
ReturnType: smartcontract.VoidType,
|
|
|
|
Parameters: []manifest.Parameter{},
|
|
|
|
})
|
|
|
|
manif.SupportedStandards = []string{manifest.NEP17StandardName}
|
2023-08-03 16:48:55 +00:00
|
|
|
c1, err := mgmt.Deploy(ic, sender, ne, manif)
|
2021-07-23 12:52:30 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2022-04-19 14:12:03 +00:00
|
|
|
// c1 contract hash should be returned, as private DAO already contains changed cache.
|
|
|
|
require.Equal(t, []util.Uint160{c1.Hash}, mgmt.GetNEP17Contracts(private))
|
|
|
|
|
|
|
|
// Lower DAO still shouldn't contain c1, as no Persist was called.
|
2022-04-12 14:29:11 +00:00
|
|
|
require.Empty(t, mgmt.GetNEP17Contracts(d))
|
2021-07-23 12:52:30 +00:00
|
|
|
|
2022-04-19 14:12:03 +00:00
|
|
|
// Call Persist, check c1 contract hash is returned
|
|
|
|
_, err = private.Persist()
|
|
|
|
require.NoError(t, err)
|
2022-04-12 14:29:11 +00:00
|
|
|
require.Equal(t, []util.Uint160{c1.Hash}, mgmt.GetNEP17Contracts(d))
|
2021-07-23 12:52:30 +00:00
|
|
|
|
|
|
|
// Update contract
|
2022-04-19 14:12:03 +00:00
|
|
|
private = d.GetPrivate()
|
2021-07-23 12:52:30 +00:00
|
|
|
manif.ABI.Methods = append(manif.ABI.Methods, manifest.Method{
|
|
|
|
Name: "dummy2",
|
|
|
|
ReturnType: smartcontract.VoidType,
|
|
|
|
Parameters: []manifest.Parameter{},
|
|
|
|
})
|
2023-08-03 16:48:55 +00:00
|
|
|
c1Updated, err := mgmt.Update(&interop.Context{DAO: private}, c1.Hash, ne, manif)
|
2021-07-23 12:52:30 +00:00
|
|
|
require.NoError(t, err)
|
2022-04-19 14:12:03 +00:00
|
|
|
require.Equal(t, c1.Hash, c1Updated.Hash)
|
2021-07-23 12:52:30 +00:00
|
|
|
|
2022-04-19 14:12:03 +00:00
|
|
|
// No changes expected in lower store.
|
2022-04-12 14:29:11 +00:00
|
|
|
require.Equal(t, []util.Uint160{c1.Hash}, mgmt.GetNEP17Contracts(d))
|
2022-09-19 19:56:33 +00:00
|
|
|
c1Lower, err := GetContract(d, c1.Hash)
|
2022-04-19 14:12:03 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, 1, len(c1Lower.Manifest.ABI.Methods))
|
|
|
|
require.Equal(t, []util.Uint160{c1Updated.Hash}, mgmt.GetNEP17Contracts(private))
|
2022-09-19 19:56:33 +00:00
|
|
|
c1Upper, err := GetContract(private, c1Updated.Hash)
|
2022-04-19 14:12:03 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, 2, len(c1Upper.Manifest.ABI.Methods))
|
2021-07-23 12:52:30 +00:00
|
|
|
|
2022-04-19 14:12:03 +00:00
|
|
|
// Call Persist, check c1Updated state is returned from lower.
|
|
|
|
_, err = private.Persist()
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, []util.Uint160{c1.Hash}, mgmt.GetNEP17Contracts(d))
|
2022-09-19 19:56:33 +00:00
|
|
|
c1Lower, err = GetContract(d, c1.Hash)
|
2022-04-19 14:12:03 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, 2, len(c1Lower.Manifest.ABI.Methods))
|
2021-07-23 12:52:30 +00:00
|
|
|
}
|