Merge pull request #2532 from nspcc-dev/statediff-fixes

core: fix T5 statediffs
This commit is contained in:
Roman Khimov 2022-06-03 11:52:28 +03:00 committed by GitHub
commit 581baab6c9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 51 additions and 9 deletions

View file

@ -282,7 +282,7 @@ func getMethod(t *testing.T, ctr interop.ContractMD, name string, params []strin
} }
md, ok := ctr.GetMethod(name, paramLen) md, ok := ctr.GetMethod(name, paramLen)
require.True(t, ok) require.True(t, ok, ctr.Manifest.Name, name, paramLen)
return md return md
} }

View file

@ -207,7 +207,7 @@ func (c *ContractMD) AddMethod(md *MethodAndPrice, desc *manifest.Method) {
index := sort.Search(len(c.Manifest.ABI.Methods), func(i int) bool { index := sort.Search(len(c.Manifest.ABI.Methods), func(i int) bool {
md := c.Manifest.ABI.Methods[i] md := c.Manifest.ABI.Methods[i]
if md.Name != desc.Name { if md.Name != desc.Name {
return md.Name >= desc.Name return strings.ToLower(md.Name) >= strings.ToLower(desc.Name)
} }
return len(md.Parameters) > len(desc.Parameters) return len(md.Parameters) > len(desc.Parameters)
}) })
@ -236,7 +236,7 @@ func (c *ContractMD) GetMethodByOffset(offset int) (MethodAndPrice, bool) {
func (c *ContractMD) GetMethod(name string, paramCount int) (MethodAndPrice, bool) { func (c *ContractMD) GetMethod(name string, paramCount int) (MethodAndPrice, bool) {
index := sort.Search(len(c.Methods), func(i int) bool { index := sort.Search(len(c.Methods), func(i int) bool {
md := c.Methods[i] md := c.Methods[i]
res := strings.Compare(name, md.MD.Name) res := strings.Compare(strings.ToLower(name), strings.ToLower(md.MD.Name))
switch res { switch res {
case -1, 1: case -1, 1:
return res == -1 return res == -1

View file

@ -967,3 +967,18 @@ func TestRuntimeCheckWitness(t *testing.T) {
}) })
}) })
} }
// TestNativeGetMethod is needed to ensure that methods list has the same sorting
// rule as we expect inside the `ContractMD.GetMethod`.
func TestNativeGetMethod(t *testing.T) {
cfg := config.ProtocolConfiguration{P2PSigExtensions: true}
cs := native.NewContracts(cfg)
for _, c := range cs.Contracts {
t.Run(c.Metadata().Name, func(t *testing.T) {
for _, m := range c.Metadata().Methods {
_, ok := c.Metadata().GetMethod(m.MD.Name, len(m.MD.Parameters))
require.True(t, ok)
}
})
}
}

View file

@ -614,7 +614,7 @@ func checkScriptAndMethods(script []byte, methods []manifest.Method) error {
offsets := bitfield.New(l) offsets := bitfield.New(l)
for i := range methods { for i := range methods {
if methods[i].Offset >= l { if methods[i].Offset >= l {
return errors.New("out of bounds method offset") continue
} }
offsets.Set(methods[i].Offset) offsets.Set(methods[i].Offset)
} }

View file

@ -205,7 +205,7 @@ func newNEO(cfg config.ProtocolConfiguration) *NEO {
n.AddMethod(md, desc) n.AddMethod(md, desc)
desc = newDescriptor("getCandidateVote", smartcontract.IntegerType, desc = newDescriptor("getCandidateVote", smartcontract.IntegerType,
manifest.NewParameter("pubkey", smartcontract.PublicKeyType)) manifest.NewParameter("pubKey", smartcontract.PublicKeyType))
md = newMethodAndPrice(n.getCandidateVoteCall, 1<<15, callflag.ReadStates) md = newMethodAndPrice(n.getCandidateVoteCall, 1<<15, callflag.ReadStates)
n.AddMethod(md, desc) n.AddMethod(md, desc)

View file

@ -135,13 +135,20 @@ func TestManagement_ContractDeploy(t *testing.T) {
badManifest := cs1.Manifest badManifest := cs1.Manifest
badManifest.ABI.Methods = make([]manifest.Method, len(cs1.Manifest.ABI.Methods)) badManifest.ABI.Methods = make([]manifest.Method, len(cs1.Manifest.ABI.Methods))
copy(badManifest.ABI.Methods, cs1.Manifest.ABI.Methods) copy(badManifest.ABI.Methods, cs1.Manifest.ABI.Methods)
badManifest.ABI.Methods[0].Offset = 100500 // out of bounds badManifest.ABI.Methods[0].Offset = 100500 // out of bounds, but it's OK, this method will not be checked then.
manifB, err := json.Marshal(&badManifest) manifB, err := json.Marshal(&badManifest)
require.NoError(t, err) require.NoError(t, err)
managementInvoker.InvokeFail(t, "out of bounds method offset", "deploy", nefBytes, manifB) tx := c.PrepareInvokeNoSign(t, "deploy", nefBytes, manifB)
}) tx.Signers = []transaction.Signer{{}} // Need dummy signer to deploy.
b := c.NewUnsignedBlock(t, tx)
ic := c.Chain.GetTestVM(trigger.Application, tx, b)
t.Cleanup(ic.Finalize)
ic.VM.LoadWithFlags(tx.Script, callflag.All)
err = ic.VM.Run()
require.NoError(t, err)
})
t.Run("bad methods in manifest 2", func(t *testing.T) { t.Run("bad methods in manifest 2", func(t *testing.T) {
var badManifest = cs1.Manifest var badManifest = cs1.Manifest
badManifest.ABI.Methods = make([]manifest.Method, len(cs1.Manifest.ABI.Methods)) badManifest.ABI.Methods = make([]manifest.Method, len(cs1.Manifest.ABI.Methods))
@ -153,6 +160,26 @@ func TestManagement_ContractDeploy(t *testing.T) {
managementInvoker.InvokeFail(t, "some methods point to wrong offsets (not to instruction boundary)", "deploy", nefBytes, manifB) managementInvoker.InvokeFail(t, "some methods point to wrong offsets (not to instruction boundary)", "deploy", nefBytes, manifB)
}) })
t.Run("duplicated methods in manifest 1", func(t *testing.T) {
badManifest := cs1.Manifest
badManifest.ABI.Methods = make([]manifest.Method, len(cs1.Manifest.ABI.Methods))
copy(badManifest.ABI.Methods, cs1.Manifest.ABI.Methods)
badManifest.ABI.Methods[0] = badManifest.ABI.Methods[1] // duplicates
manifB, err := json.Marshal(&badManifest)
require.NoError(t, err)
managementInvoker.InvokeFail(t, "duplicate method specifications", "deploy", nefBytes, manifB)
})
t.Run("duplicated events in manifest 1", func(t *testing.T) {
badManifest := cs1.Manifest
badManifest.ABI.Methods = make([]manifest.Method, len(cs1.Manifest.ABI.Methods))
copy(badManifest.ABI.Methods, cs1.Manifest.ABI.Methods)
badManifest.ABI.Events = []manifest.Event{{Name: "event"}, {Name: "event"}} // duplicates
manifB, err := json.Marshal(&badManifest)
require.NoError(t, err)
managementInvoker.InvokeFail(t, "duplicate event names", "deploy", nefBytes, manifB)
})
t.Run("not enough GAS", func(t *testing.T) { t.Run("not enough GAS", func(t *testing.T) {
tx := managementInvoker.NewUnsignedTx(t, managementInvoker.Hash, "deploy", nefBytes, manifestBytes) tx := managementInvoker.NewUnsignedTx(t, managementInvoker.Hash, "deploy", nefBytes, manifestBytes)

View file

@ -75,7 +75,7 @@ const (
nfsoContractHash = "c7ec8e0fb4d669913e4ffdd4ba4fa3502e5d2d10" nfsoContractHash = "c7ec8e0fb4d669913e4ffdd4ba4fa3502e5d2d10"
nfsoToken1ID = "7e244ffd6aa85fb1579d2ed22e9b761ab62e3486" nfsoToken1ID = "7e244ffd6aa85fb1579d2ed22e9b761ab62e3486"
invokescriptContractAVM = "VwIADBQBDAMOBQYMDQIODw0DDgcJAAAAAErZMCQE2zBwaEH4J+yMqiYEEUAMFA0PAwIJAAIBAwcDBAUCAQAOBgwJStkwJATbMHFpQfgn7IyqJgQSQBNA" invokescriptContractAVM = "VwIADBQBDAMOBQYMDQIODw0DDgcJAAAAAErZMCQE2zBwaEH4J+yMqiYEEUAMFA0PAwIJAAIBAwcDBAUCAQAOBgwJStkwJATbMHFpQfgn7IyqJgQSQBNA"
block20StateRootLE = "93ebfc8b030de02c5548ae08ac4a0ea39c12c82e62609ae07bdf3d803bcf9ffd" block20StateRootLE = "3cba730383c4c2c34475939a4efe9de9ac377bffaf0abdb6f8a1a8fe145d8f69"
) )
var ( var (