Merge pull request #1736 from nspcc-dev/preview5-compatibility-fixes
core: preview-5 states difference fixes
This commit is contained in:
commit
754c985424
10 changed files with 46 additions and 38 deletions
|
@ -1,6 +1,7 @@
|
||||||
package compiler
|
package compiler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/internal/testserdes"
|
"github.com/nspcc-dev/neo-go/internal/testserdes"
|
||||||
|
@ -265,7 +266,7 @@ func _deploy(data interface{}, isUpdate bool) {}
|
||||||
Trusts: manifest.WildUint160s{
|
Trusts: manifest.WildUint160s{
|
||||||
Value: []util.Uint160{},
|
Value: []util.Uint160{},
|
||||||
},
|
},
|
||||||
Extra: nil,
|
Extra: json.RawMessage("null"),
|
||||||
}
|
}
|
||||||
require.ElementsMatch(t, expected.ABI.Methods, actual.ABI.Methods)
|
require.ElementsMatch(t, expected.ABI.Methods, actual.ABI.Methods)
|
||||||
require.Equal(t, expected.ABI.Events, actual.ABI.Events)
|
require.Equal(t, expected.ABI.Events, actual.ABI.Events)
|
||||||
|
|
|
@ -53,12 +53,12 @@ func newLedger() *Ledger {
|
||||||
l.AddMethod(md, desc)
|
l.AddMethod(md, desc)
|
||||||
|
|
||||||
desc = newDescriptor("getTransaction", smartcontract.ArrayType,
|
desc = newDescriptor("getTransaction", smartcontract.ArrayType,
|
||||||
manifest.NewParameter("hash", smartcontract.ByteArrayType))
|
manifest.NewParameter("hash", smartcontract.Hash256Type))
|
||||||
md = newMethodAndPrice(l.getTransaction, 1000000, callflag.ReadStates)
|
md = newMethodAndPrice(l.getTransaction, 1000000, callflag.ReadStates)
|
||||||
l.AddMethod(md, desc)
|
l.AddMethod(md, desc)
|
||||||
|
|
||||||
desc = newDescriptor("getTransactionHeight", smartcontract.IntegerType,
|
desc = newDescriptor("getTransactionHeight", smartcontract.IntegerType,
|
||||||
manifest.NewParameter("hash", smartcontract.ByteArrayType))
|
manifest.NewParameter("hash", smartcontract.Hash256Type))
|
||||||
md = newMethodAndPrice(l.getTransactionHeight, 1000000, callflag.ReadStates)
|
md = newMethodAndPrice(l.getTransactionHeight, 1000000, callflag.ReadStates)
|
||||||
l.AddMethod(md, desc)
|
l.AddMethod(md, desc)
|
||||||
|
|
||||||
|
|
|
@ -72,26 +72,26 @@ func newManagement() *Management {
|
||||||
m.AddMethod(md, desc)
|
m.AddMethod(md, desc)
|
||||||
|
|
||||||
desc = newDescriptor("deploy", smartcontract.ArrayType,
|
desc = newDescriptor("deploy", smartcontract.ArrayType,
|
||||||
manifest.NewParameter("script", smartcontract.ByteArrayType),
|
manifest.NewParameter("nefFile", smartcontract.ByteArrayType),
|
||||||
manifest.NewParameter("manifest", smartcontract.ByteArrayType))
|
manifest.NewParameter("manifest", smartcontract.ByteArrayType))
|
||||||
md = newMethodAndPrice(m.deploy, 0, callflag.WriteStates|callflag.AllowNotify)
|
md = newMethodAndPrice(m.deploy, 0, callflag.WriteStates|callflag.AllowNotify)
|
||||||
m.AddMethod(md, desc)
|
m.AddMethod(md, desc)
|
||||||
|
|
||||||
desc = newDescriptor("deploy", smartcontract.ArrayType,
|
desc = newDescriptor("deploy", smartcontract.ArrayType,
|
||||||
manifest.NewParameter("script", smartcontract.ByteArrayType),
|
manifest.NewParameter("nefFile", smartcontract.ByteArrayType),
|
||||||
manifest.NewParameter("manifest", smartcontract.ByteArrayType),
|
manifest.NewParameter("manifest", smartcontract.ByteArrayType),
|
||||||
manifest.NewParameter("data", smartcontract.AnyType))
|
manifest.NewParameter("data", smartcontract.AnyType))
|
||||||
md = newMethodAndPrice(m.deployWithData, 0, callflag.WriteStates|callflag.AllowNotify)
|
md = newMethodAndPrice(m.deployWithData, 0, callflag.WriteStates|callflag.AllowNotify)
|
||||||
m.AddMethod(md, desc)
|
m.AddMethod(md, desc)
|
||||||
|
|
||||||
desc = newDescriptor("update", smartcontract.VoidType,
|
desc = newDescriptor("update", smartcontract.VoidType,
|
||||||
manifest.NewParameter("script", smartcontract.ByteArrayType),
|
manifest.NewParameter("nefFile", smartcontract.ByteArrayType),
|
||||||
manifest.NewParameter("manifest", smartcontract.ByteArrayType))
|
manifest.NewParameter("manifest", smartcontract.ByteArrayType))
|
||||||
md = newMethodAndPrice(m.update, 0, callflag.WriteStates|callflag.AllowNotify)
|
md = newMethodAndPrice(m.update, 0, callflag.WriteStates|callflag.AllowNotify)
|
||||||
m.AddMethod(md, desc)
|
m.AddMethod(md, desc)
|
||||||
|
|
||||||
desc = newDescriptor("update", smartcontract.VoidType,
|
desc = newDescriptor("update", smartcontract.VoidType,
|
||||||
manifest.NewParameter("script", smartcontract.ByteArrayType),
|
manifest.NewParameter("nefFile", smartcontract.ByteArrayType),
|
||||||
manifest.NewParameter("manifest", smartcontract.ByteArrayType),
|
manifest.NewParameter("manifest", smartcontract.ByteArrayType),
|
||||||
manifest.NewParameter("data", smartcontract.AnyType))
|
manifest.NewParameter("data", smartcontract.AnyType))
|
||||||
md = newMethodAndPrice(m.updateWithData, 0, callflag.WriteStates|callflag.AllowNotify)
|
md = newMethodAndPrice(m.updateWithData, 0, callflag.WriteStates|callflag.AllowNotify)
|
||||||
|
|
|
@ -125,7 +125,7 @@ func newNEO() *NEO {
|
||||||
|
|
||||||
desc = newDescriptor("vote", smartcontract.BoolType,
|
desc = newDescriptor("vote", smartcontract.BoolType,
|
||||||
manifest.NewParameter("account", smartcontract.Hash160Type),
|
manifest.NewParameter("account", smartcontract.Hash160Type),
|
||||||
manifest.NewParameter("pubkey", smartcontract.ByteArrayType))
|
manifest.NewParameter("voteTo", smartcontract.ByteArrayType))
|
||||||
md = newMethodAndPrice(n.vote, 5000000, callflag.WriteStates)
|
md = newMethodAndPrice(n.vote, 5000000, callflag.WriteStates)
|
||||||
n.AddMethod(md, desc)
|
n.AddMethod(md, desc)
|
||||||
|
|
||||||
|
|
|
@ -258,13 +258,19 @@ func (c *nep17TokenNative) addTokens(ic *interop.Context, h util.Uint160, amount
|
||||||
if err := c.incBalance(ic, h, si, amount); err != nil {
|
if err := c.incBalance(ic, h, si, amount); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if err := ic.DAO.PutStorageItem(c.ID, key, si); err != nil {
|
var err error
|
||||||
|
if si.Value == nil {
|
||||||
|
err = ic.DAO.DeleteStorageItem(c.ID, key)
|
||||||
|
} else {
|
||||||
|
err = ic.DAO.PutStorageItem(c.ID, key, si)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
supply := c.getTotalSupply(ic.DAO)
|
supply := c.getTotalSupply(ic.DAO)
|
||||||
supply.Add(supply, amount)
|
supply.Add(supply, amount)
|
||||||
err := c.saveTotalSupply(ic.DAO, supply)
|
err = c.saveTotalSupply(ic.DAO, supply)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,11 +95,11 @@ func newNonFungible(name string, id int32, symbol string, decimals byte) *nonfun
|
||||||
md = newMethodAndPrice(n.Properties, 1000000, callflag.ReadStates)
|
md = newMethodAndPrice(n.Properties, 1000000, callflag.ReadStates)
|
||||||
n.AddMethod(md, desc)
|
n.AddMethod(md, desc)
|
||||||
|
|
||||||
desc = newDescriptor("tokens", smartcontract.InteropInterfaceType)
|
desc = newDescriptor("tokens", smartcontract.AnyType)
|
||||||
md = newMethodAndPrice(n.tokens, 1000000, callflag.ReadStates)
|
md = newMethodAndPrice(n.tokens, 1000000, callflag.ReadStates)
|
||||||
n.AddMethod(md, desc)
|
n.AddMethod(md, desc)
|
||||||
|
|
||||||
desc = newDescriptor("tokensOf", smartcontract.InteropInterfaceType,
|
desc = newDescriptor("tokensOf", smartcontract.AnyType,
|
||||||
manifest.NewParameter("owner", smartcontract.Hash160Type))
|
manifest.NewParameter("owner", smartcontract.Hash160Type))
|
||||||
md = newMethodAndPrice(n.tokensOf, 1000000, callflag.ReadStates)
|
md = newMethodAndPrice(n.tokensOf, 1000000, callflag.ReadStates)
|
||||||
n.AddMethod(md, desc)
|
n.AddMethod(md, desc)
|
||||||
|
|
|
@ -481,7 +481,7 @@ func TestContractUpdate(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
cs1.Manifest.Extra = "update me"
|
cs1.Manifest.Extra = []byte(`"update me"`)
|
||||||
manif1, err = json.Marshal(cs1.Manifest)
|
manif1, err = json.Marshal(cs1.Manifest)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
cs1.UpdateCounter++
|
cs1.UpdateCounter++
|
||||||
|
@ -504,7 +504,7 @@ func TestContractUpdate(t *testing.T) {
|
||||||
cs1.NEF.Checksum = cs1.NEF.CalculateChecksum()
|
cs1.NEF.Checksum = cs1.NEF.CalculateChecksum()
|
||||||
nef1b, err = cs1.NEF.Bytes()
|
nef1b, err = cs1.NEF.Bytes()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
cs1.Manifest.Extra = "update me once more"
|
cs1.Manifest.Extra = []byte(`"update me once more"`)
|
||||||
manif1, err = json.Marshal(cs1.Manifest)
|
manif1, err = json.Marshal(cs1.Manifest)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
cs1.UpdateCounter++
|
cs1.UpdateCounter++
|
||||||
|
|
|
@ -34,7 +34,7 @@ type Manifest struct {
|
||||||
// Trusts is a set of hashes to a which contract trusts.
|
// Trusts is a set of hashes to a which contract trusts.
|
||||||
Trusts WildUint160s `json:"trusts"`
|
Trusts WildUint160s `json:"trusts"`
|
||||||
// Extra is an implementation-defined user data.
|
// Extra is an implementation-defined user data.
|
||||||
Extra interface{} `json:"extra"`
|
Extra json.RawMessage `json:"extra"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewManifest returns new manifest with necessary fields initialized.
|
// NewManifest returns new manifest with necessary fields initialized.
|
||||||
|
@ -48,6 +48,7 @@ func NewManifest(name string) *Manifest {
|
||||||
Groups: []Group{},
|
Groups: []Group{},
|
||||||
Permissions: []Permission{},
|
Permissions: []Permission{},
|
||||||
SupportedStandards: []string{},
|
SupportedStandards: []string{},
|
||||||
|
Extra: json.RawMessage("null"),
|
||||||
}
|
}
|
||||||
m.Trusts.Restrict()
|
m.Trusts.Restrict()
|
||||||
return m
|
return m
|
||||||
|
@ -143,11 +144,7 @@ func (m *Manifest) ToStackItem() (stackitem.Item, error) {
|
||||||
}
|
}
|
||||||
extra := stackitem.Make("null")
|
extra := stackitem.Make("null")
|
||||||
if m.Extra != nil {
|
if m.Extra != nil {
|
||||||
e, err := json.Marshal(m.Extra)
|
extra = stackitem.NewByteArray(m.Extra)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
extra = stackitem.NewByteArray(e)
|
|
||||||
}
|
}
|
||||||
return stackitem.NewStruct([]stackitem.Item{
|
return stackitem.NewStruct([]stackitem.Item{
|
||||||
stackitem.Make(m.Name),
|
stackitem.Make(m.Name),
|
||||||
|
@ -238,8 +235,6 @@ func (m *Manifest) FromStackItem(item stackitem.Item) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if string(extra) == "null" {
|
m.Extra = extra
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return json.Unmarshal(extra, &m.Extra)
|
|
||||||
}
|
|
||||||
|
|
|
@ -278,7 +278,7 @@ func TestManifestToStackItem(t *testing.T) {
|
||||||
Trusts: WildUint160s{
|
Trusts: WildUint160s{
|
||||||
Value: []util.Uint160{{1, 2, 3}},
|
Value: []util.Uint160{{1, 2, 3}},
|
||||||
},
|
},
|
||||||
Extra: "some extra data",
|
Extra: []byte(`even not a json allowed`),
|
||||||
}
|
}
|
||||||
check(t, expected)
|
check(t, expected)
|
||||||
})
|
})
|
||||||
|
@ -335,14 +335,6 @@ func TestManifest_FromStackItemErrors(t *testing.T) {
|
||||||
stackitem.NewArray([]stackitem.Item{}),
|
stackitem.NewArray([]stackitem.Item{}),
|
||||||
stackitem.NewArray([]stackitem.Item{}),
|
stackitem.NewArray([]stackitem.Item{}),
|
||||||
stackitem.Null{}}),
|
stackitem.Null{}}),
|
||||||
"invalid extra": stackitem.NewStruct([]stackitem.Item{
|
|
||||||
stackitem.NewByteArray([]byte{}),
|
|
||||||
stackitem.NewArray([]stackitem.Item{}),
|
|
||||||
stackitem.NewArray([]stackitem.Item{}),
|
|
||||||
stackitem.NewStruct([]stackitem.Item{stackitem.NewArray([]stackitem.Item{}), stackitem.NewArray([]stackitem.Item{})}),
|
|
||||||
stackitem.NewArray([]stackitem.Item{}),
|
|
||||||
stackitem.NewArray([]stackitem.Item{}),
|
|
||||||
stackitem.NewByteArray([]byte("not a json"))}),
|
|
||||||
}
|
}
|
||||||
for name, errCase := range errCases {
|
for name, errCase := range errCases {
|
||||||
t.Run(name, func(t *testing.T) {
|
t.Run(name, func(t *testing.T) {
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/binary"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -12,6 +15,8 @@ import (
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ledgerContractID = -2
|
||||||
|
|
||||||
type dump []blockDump
|
type dump []blockDump
|
||||||
|
|
||||||
type blockDump struct {
|
type blockDump struct {
|
||||||
|
@ -39,15 +44,27 @@ func readFile(path string) (dump, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d dump) normalize() {
|
func (d dump) normalize() {
|
||||||
|
ledgerIDBytes := make([]byte, 4)
|
||||||
|
binary.LittleEndian.PutUint32(ledgerIDBytes, uint32(ledgerContractID))
|
||||||
for i := range d {
|
for i := range d {
|
||||||
|
var newStorage []storageOp
|
||||||
for j := range d[i].Storage {
|
for j := range d[i].Storage {
|
||||||
|
keyBytes, err := base64.StdEncoding.DecodeString(d[i].Storage[j].Key)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Errorf("invalid key encoding: %w", err))
|
||||||
|
}
|
||||||
|
if bytes.HasPrefix(keyBytes, ledgerIDBytes) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if d[i].Storage[j].State == "Changed" {
|
if d[i].Storage[j].State == "Changed" {
|
||||||
d[i].Storage[j].State = "Added"
|
d[i].Storage[j].State = "Added"
|
||||||
}
|
}
|
||||||
|
newStorage = append(newStorage, d[i].Storage[j])
|
||||||
}
|
}
|
||||||
sort.Slice(d[i].Storage, func(k, l int) bool {
|
sort.Slice(newStorage, func(k, l int) bool {
|
||||||
return d[i].Storage[k].Key < d[i].Storage[l].Key
|
return newStorage[k].Key < newStorage[l].Key
|
||||||
})
|
})
|
||||||
|
d[i].Storage = newStorage
|
||||||
}
|
}
|
||||||
// assume that d is already sorted by Block
|
// assume that d is already sorted by Block
|
||||||
}
|
}
|
||||||
|
@ -72,9 +89,6 @@ func compare(a, b string) error {
|
||||||
if blockA.Block != blockB.Block {
|
if blockA.Block != blockB.Block {
|
||||||
return fmt.Errorf("block number mismatch: %d vs %d", blockA.Block, blockB.Block)
|
return fmt.Errorf("block number mismatch: %d vs %d", blockA.Block, blockB.Block)
|
||||||
}
|
}
|
||||||
if blockA.Size != blockB.Size {
|
|
||||||
return fmt.Errorf("block %d, changes number mismatch: %d vs %d", blockA.Block, blockA.Size, blockB.Size)
|
|
||||||
}
|
|
||||||
if len(blockA.Storage) != len(blockB.Storage) {
|
if len(blockA.Storage) != len(blockB.Storage) {
|
||||||
return fmt.Errorf("block %d, changes length mismatch: %d vs %d", blockA.Block, len(blockA.Storage), len(blockB.Storage))
|
return fmt.Errorf("block %d, changes length mismatch: %d vs %d", blockA.Block, len(blockA.Storage), len(blockB.Storage))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue