diff --git a/pkg/compiler/debug_test.go b/pkg/compiler/debug_test.go index 5e1c0346d..08d5da8f9 100644 --- a/pkg/compiler/debug_test.go +++ b/pkg/compiler/debug_test.go @@ -1,6 +1,7 @@ package compiler import ( + "encoding/json" "testing" "github.com/nspcc-dev/neo-go/internal/testserdes" @@ -265,7 +266,7 @@ func _deploy(data interface{}, isUpdate bool) {} Trusts: manifest.WildUint160s{ Value: []util.Uint160{}, }, - Extra: nil, + Extra: json.RawMessage("null"), } require.ElementsMatch(t, expected.ABI.Methods, actual.ABI.Methods) require.Equal(t, expected.ABI.Events, actual.ABI.Events) diff --git a/pkg/core/native/ledger.go b/pkg/core/native/ledger.go index b521238ce..15817910d 100644 --- a/pkg/core/native/ledger.go +++ b/pkg/core/native/ledger.go @@ -53,12 +53,12 @@ func newLedger() *Ledger { l.AddMethod(md, desc) desc = newDescriptor("getTransaction", smartcontract.ArrayType, - manifest.NewParameter("hash", smartcontract.ByteArrayType)) + manifest.NewParameter("hash", smartcontract.Hash256Type)) md = newMethodAndPrice(l.getTransaction, 1000000, callflag.ReadStates) l.AddMethod(md, desc) desc = newDescriptor("getTransactionHeight", smartcontract.IntegerType, - manifest.NewParameter("hash", smartcontract.ByteArrayType)) + manifest.NewParameter("hash", smartcontract.Hash256Type)) md = newMethodAndPrice(l.getTransactionHeight, 1000000, callflag.ReadStates) l.AddMethod(md, desc) diff --git a/pkg/core/native/management.go b/pkg/core/native/management.go index 8b7e534a1..a2787ac80 100644 --- a/pkg/core/native/management.go +++ b/pkg/core/native/management.go @@ -72,26 +72,26 @@ func newManagement() *Management { m.AddMethod(md, desc) desc = newDescriptor("deploy", smartcontract.ArrayType, - manifest.NewParameter("script", smartcontract.ByteArrayType), + manifest.NewParameter("nefFile", smartcontract.ByteArrayType), manifest.NewParameter("manifest", smartcontract.ByteArrayType)) md = newMethodAndPrice(m.deploy, 0, callflag.WriteStates|callflag.AllowNotify) m.AddMethod(md, desc) desc = newDescriptor("deploy", smartcontract.ArrayType, - manifest.NewParameter("script", smartcontract.ByteArrayType), + manifest.NewParameter("nefFile", smartcontract.ByteArrayType), manifest.NewParameter("manifest", smartcontract.ByteArrayType), manifest.NewParameter("data", smartcontract.AnyType)) md = newMethodAndPrice(m.deployWithData, 0, callflag.WriteStates|callflag.AllowNotify) m.AddMethod(md, desc) desc = newDescriptor("update", smartcontract.VoidType, - manifest.NewParameter("script", smartcontract.ByteArrayType), + manifest.NewParameter("nefFile", smartcontract.ByteArrayType), manifest.NewParameter("manifest", smartcontract.ByteArrayType)) md = newMethodAndPrice(m.update, 0, callflag.WriteStates|callflag.AllowNotify) m.AddMethod(md, desc) desc = newDescriptor("update", smartcontract.VoidType, - manifest.NewParameter("script", smartcontract.ByteArrayType), + manifest.NewParameter("nefFile", smartcontract.ByteArrayType), manifest.NewParameter("manifest", smartcontract.ByteArrayType), manifest.NewParameter("data", smartcontract.AnyType)) md = newMethodAndPrice(m.updateWithData, 0, callflag.WriteStates|callflag.AllowNotify) diff --git a/pkg/core/native/native_neo.go b/pkg/core/native/native_neo.go index 57f83d713..6c35b1b22 100644 --- a/pkg/core/native/native_neo.go +++ b/pkg/core/native/native_neo.go @@ -125,7 +125,7 @@ func newNEO() *NEO { desc = newDescriptor("vote", smartcontract.BoolType, manifest.NewParameter("account", smartcontract.Hash160Type), - manifest.NewParameter("pubkey", smartcontract.ByteArrayType)) + manifest.NewParameter("voteTo", smartcontract.ByteArrayType)) md = newMethodAndPrice(n.vote, 5000000, callflag.WriteStates) n.AddMethod(md, desc) diff --git a/pkg/core/native/native_nep17.go b/pkg/core/native/native_nep17.go index 7c2a0f1c7..359f65f25 100644 --- a/pkg/core/native/native_nep17.go +++ b/pkg/core/native/native_nep17.go @@ -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 { 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) } supply := c.getTotalSupply(ic.DAO) supply.Add(supply, amount) - err := c.saveTotalSupply(ic.DAO, supply) + err = c.saveTotalSupply(ic.DAO, supply) if err != nil { panic(err) } diff --git a/pkg/core/native/nonfungible.go b/pkg/core/native/nonfungible.go index afbfd7292..0aa2239ba 100644 --- a/pkg/core/native/nonfungible.go +++ b/pkg/core/native/nonfungible.go @@ -95,11 +95,11 @@ func newNonFungible(name string, id int32, symbol string, decimals byte) *nonfun md = newMethodAndPrice(n.Properties, 1000000, callflag.ReadStates) n.AddMethod(md, desc) - desc = newDescriptor("tokens", smartcontract.InteropInterfaceType) + desc = newDescriptor("tokens", smartcontract.AnyType) md = newMethodAndPrice(n.tokens, 1000000, callflag.ReadStates) n.AddMethod(md, desc) - desc = newDescriptor("tokensOf", smartcontract.InteropInterfaceType, + desc = newDescriptor("tokensOf", smartcontract.AnyType, manifest.NewParameter("owner", smartcontract.Hash160Type)) md = newMethodAndPrice(n.tokensOf, 1000000, callflag.ReadStates) n.AddMethod(md, desc) diff --git a/pkg/core/native_management_test.go b/pkg/core/native_management_test.go index b0ba0082a..1445fd901 100644 --- a/pkg/core/native_management_test.go +++ b/pkg/core/native_management_test.go @@ -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) require.NoError(t, err) cs1.UpdateCounter++ @@ -504,7 +504,7 @@ func TestContractUpdate(t *testing.T) { cs1.NEF.Checksum = cs1.NEF.CalculateChecksum() nef1b, err = cs1.NEF.Bytes() 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) require.NoError(t, err) cs1.UpdateCounter++ diff --git a/pkg/smartcontract/manifest/manifest.go b/pkg/smartcontract/manifest/manifest.go index c7bbd0fe7..31a3011a4 100644 --- a/pkg/smartcontract/manifest/manifest.go +++ b/pkg/smartcontract/manifest/manifest.go @@ -34,7 +34,7 @@ type Manifest struct { // Trusts is a set of hashes to a which contract trusts. Trusts WildUint160s `json:"trusts"` // Extra is an implementation-defined user data. - Extra interface{} `json:"extra"` + Extra json.RawMessage `json:"extra"` } // NewManifest returns new manifest with necessary fields initialized. @@ -48,6 +48,7 @@ func NewManifest(name string) *Manifest { Groups: []Group{}, Permissions: []Permission{}, SupportedStandards: []string{}, + Extra: json.RawMessage("null"), } m.Trusts.Restrict() return m @@ -143,11 +144,7 @@ func (m *Manifest) ToStackItem() (stackitem.Item, error) { } extra := stackitem.Make("null") if m.Extra != nil { - e, err := json.Marshal(m.Extra) - if err != nil { - return nil, err - } - extra = stackitem.NewByteArray(e) + extra = stackitem.NewByteArray(m.Extra) } return stackitem.NewStruct([]stackitem.Item{ stackitem.Make(m.Name), @@ -238,8 +235,6 @@ func (m *Manifest) FromStackItem(item stackitem.Item) error { if err != nil { return err } - if string(extra) == "null" { - return nil - } - return json.Unmarshal(extra, &m.Extra) + m.Extra = extra + return nil } diff --git a/pkg/smartcontract/manifest/manifest_test.go b/pkg/smartcontract/manifest/manifest_test.go index 60a917252..4532dcbba 100644 --- a/pkg/smartcontract/manifest/manifest_test.go +++ b/pkg/smartcontract/manifest/manifest_test.go @@ -278,7 +278,7 @@ func TestManifestToStackItem(t *testing.T) { Trusts: WildUint160s{ Value: []util.Uint160{{1, 2, 3}}, }, - Extra: "some extra data", + Extra: []byte(`even not a json allowed`), } check(t, expected) }) @@ -335,14 +335,6 @@ func TestManifest_FromStackItemErrors(t *testing.T) { stackitem.NewArray([]stackitem.Item{}), stackitem.NewArray([]stackitem.Item{}), 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 { t.Run(name, func(t *testing.T) { diff --git a/scripts/compare-dumps.go b/scripts/compare-dumps.go index f3ca4e48c..d18897d29 100644 --- a/scripts/compare-dumps.go +++ b/scripts/compare-dumps.go @@ -1,6 +1,9 @@ package main import ( + "bytes" + "encoding/base64" + "encoding/binary" "encoding/json" "errors" "fmt" @@ -12,6 +15,8 @@ import ( "github.com/urfave/cli" ) +var ledgerContractID = -2 + type dump []blockDump type blockDump struct { @@ -39,15 +44,27 @@ func readFile(path string) (dump, error) { } func (d dump) normalize() { + ledgerIDBytes := make([]byte, 4) + binary.LittleEndian.PutUint32(ledgerIDBytes, uint32(ledgerContractID)) for i := range d { + var newStorage []storageOp 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" { d[i].Storage[j].State = "Added" } + newStorage = append(newStorage, d[i].Storage[j]) } - sort.Slice(d[i].Storage, func(k, l int) bool { - return d[i].Storage[k].Key < d[i].Storage[l].Key + sort.Slice(newStorage, func(k, l int) bool { + return newStorage[k].Key < newStorage[l].Key }) + d[i].Storage = newStorage } // assume that d is already sorted by Block } @@ -72,9 +89,6 @@ func compare(a, b string) error { if 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) { return fmt.Errorf("block %d, changes length mismatch: %d vs %d", blockA.Block, len(blockA.Storage), len(blockB.Storage)) }