From 260bcd373cad41c00745c32e1f54463b7cf07b29 Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Tue, 2 Feb 2021 18:46:43 +0300 Subject: [PATCH] core: store initial native values into DAO --- internal/fakechain/fakechain.go | 2 +- pkg/core/blockchain.go | 6 +++ pkg/core/interop_system_test.go | 10 ++--- pkg/core/native/management.go | 24 ++++++------ pkg/core/native/management_test.go | 4 +- pkg/core/native/name_service.go | 7 ++-- pkg/core/native/nonfungible.go | 9 +++-- pkg/core/native/notary.go | 11 ++++-- pkg/core/native/oracle.go | 10 +++-- pkg/core/native/policy.go | 60 ++++++++++++++++++++---------- pkg/core/native/util.go | 20 ++++++++++ pkg/core/native_oracle_test.go | 16 ++++---- pkg/core/native_policy_test.go | 4 +- pkg/core/oracle_test.go | 52 +++++++++++++------------- 14 files changed, 147 insertions(+), 88 deletions(-) diff --git a/internal/fakechain/fakechain.go b/internal/fakechain/fakechain.go index 3b79ebc8b..97d690a6c 100644 --- a/internal/fakechain/fakechain.go +++ b/internal/fakechain/fakechain.go @@ -118,7 +118,7 @@ func (chain *FakeChain) GetBaseExecFee() int64 { // GetStoragePrice implements Policer interface. func (chain *FakeChain) GetStoragePrice() int64 { - return native.StoragePrice + return native.DefaultStoragePrice } // GetMaxVerificationGAS implements Policer interface. diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 20481bd02..93000f95f 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -1918,6 +1918,9 @@ func (bc *Blockchain) GetPolicer() blockchainer.Policer { // GetBaseExecFee return execution price for `NOP`. func (bc *Blockchain) GetBaseExecFee() int64 { + if bc.BlockHeight() == 0 { + return interop.DefaultBaseExecFee + } return bc.contracts.Policy.GetExecFeeFactorInternal(bc.dao) } @@ -1938,6 +1941,9 @@ func (bc *Blockchain) GetMaxVerificationGAS() int64 { // GetStoragePrice returns current storage price. func (bc *Blockchain) GetStoragePrice() int64 { + if bc.BlockHeight() == 0 { + return native.DefaultStoragePrice + } return bc.contracts.Policy.GetStoragePriceInternal(bc.dao) } diff --git a/pkg/core/interop_system_test.go b/pkg/core/interop_system_test.go index 9b574242e..39fe5af80 100644 --- a/pkg/core/interop_system_test.go +++ b/pkg/core/interop_system_test.go @@ -355,23 +355,23 @@ func TestStoragePut(t *testing.T) { } t.Run("create, not enough gas", func(t *testing.T) { - initVM(t, []byte{1}, []byte{2, 3}, 2*native.StoragePrice) + initVM(t, []byte{1}, []byte{2, 3}, 2*native.DefaultStoragePrice) err := storagePut(ic) require.True(t, errors.Is(err, errGasLimitExceeded), "got: %v", err) }) - initVM(t, []byte{4}, []byte{5, 6}, 3*native.StoragePrice) + initVM(t, []byte{4}, []byte{5, 6}, 3*native.DefaultStoragePrice) require.NoError(t, storagePut(ic)) t.Run("update", func(t *testing.T) { t.Run("not enough gas", func(t *testing.T) { - initVM(t, []byte{4}, []byte{5, 6, 7, 8}, native.StoragePrice) + initVM(t, []byte{4}, []byte{5, 6, 7, 8}, native.DefaultStoragePrice) err := storagePut(ic) require.True(t, errors.Is(err, errGasLimitExceeded), "got: %v", err) }) - initVM(t, []byte{4}, []byte{5, 6, 7, 8}, 3*native.StoragePrice) + initVM(t, []byte{4}, []byte{5, 6, 7, 8}, 3*native.DefaultStoragePrice) require.NoError(t, storagePut(ic)) - initVM(t, []byte{4}, []byte{5, 6}, native.StoragePrice) + initVM(t, []byte{4}, []byte{5, 6}, native.DefaultStoragePrice) require.NoError(t, storagePut(ic)) }) diff --git a/pkg/core/native/management.go b/pkg/core/native/management.go index 083829570..217168afc 100644 --- a/pkg/core/native/management.go +++ b/pkg/core/native/management.go @@ -33,9 +33,6 @@ type Management struct { contracts map[util.Uint160]*state.Contract } -// StoragePrice is the price to pay for 1 byte of storage. -const StoragePrice = 100000 - const ( managementContractID = -1 @@ -386,7 +383,7 @@ func (m *Management) getMinimumDeploymentFee(ic *interop.Context, args []stackit // GetMinimumDeploymentFee returns the minimum required fee for contract deploy. func (m *Management) GetMinimumDeploymentFee(dao dao.DAO) int64 { - return int64(getUint32WithKey(m.ContractID, dao, keyMinimumDeploymentFee, defaultMinimumDeploymentFee)) + return getIntWithKey(m.ContractID, dao, keyMinimumDeploymentFee) } func (m *Management) setMinimumDeploymentFee(ic *interop.Context, args []stackitem.Item) stackitem.Item { @@ -397,7 +394,7 @@ func (m *Management) setMinimumDeploymentFee(ic *interop.Context, args []stackit if !m.NEO.checkCommittee(ic) { panic("invalid committee signature") } - err := setUint32WithKey(m.ContractID, ic.DAO, keyMinimumDeploymentFee, value) + err := setIntWithKey(m.ContractID, ic.DAO, keyMinimumDeploymentFee, int64(value)) if err != nil { panic(err) } @@ -508,7 +505,10 @@ func (m *Management) PostPersist(ic *interop.Context) error { // Initialize implements Contract interface. func (m *Management) Initialize(ic *interop.Context) error { - return setUint32WithKey(m.ContractID, ic.DAO, keyMinimumDeploymentFee, defaultMinimumDeploymentFee) + if err := setIntWithKey(m.ContractID, ic.DAO, keyMinimumDeploymentFee, defaultMinimumDeploymentFee); err != nil { + return err + } + return setIntWithKey(m.ContractID, ic.DAO, keyNextAvailableID, 1) } // PutContractState saves given contract state into given DAO. @@ -525,16 +525,14 @@ func (m *Management) PutContractState(d dao.DAO, cs *state.Contract) error { } func (m *Management) getNextContractID(d dao.DAO) (int32, error) { - var id = big.NewInt(1) si := d.GetStorageItem(m.ContractID, keyNextAvailableID) - if si != nil { - id = bigint.FromBytes(si.Value) - } else { - si = new(state.StorageItem) - si.Value = make([]byte, 0, 2) + if si == nil { + return 0, errors.New("nextAvailableID is not initialized") + } + id := bigint.FromBytes(si.Value) ret := int32(id.Int64()) - id.Add(id, big.NewInt(1)) + id.Add(id, intOne) si.Value = bigint.ToPreallocatedBytes(id, si.Value) return ret, d.PutStorageItem(m.ContractID, keyNextAvailableID, si) } diff --git a/pkg/core/native/management_test.go b/pkg/core/native/management_test.go index fa654e985..dd66e86d7 100644 --- a/pkg/core/native/management_test.go +++ b/pkg/core/native/management_test.go @@ -5,6 +5,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/core/dao" + "github.com/nspcc-dev/neo-go/pkg/core/interop" "github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/storage" "github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest" @@ -15,7 +16,8 @@ import ( func TestDeployGetUpdateDestroyContract(t *testing.T) { mgmt := newManagement() - d := dao.NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet, false) + d := dao.NewCached(dao.NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet, false)) + mgmt.Initialize(&interop.Context{DAO: d}) script := []byte{1} sender := util.Uint160{1, 2, 3} ne, err := nef.NewFile(script) diff --git a/pkg/core/native/name_service.go b/pkg/core/native/name_service.go index 0690cb414..4727ec216 100644 --- a/pkg/core/native/name_service.go +++ b/pkg/core/native/name_service.go @@ -172,11 +172,12 @@ func (n *NameService) Metadata() *interop.ContractMD { // Initialize implements interop.Contract interface. func (n *NameService) Initialize(ic *interop.Context) error { - si := &state.StorageItem{Value: bigint.ToBytes(big.NewInt(DefaultDomainPrice))} - if err := ic.DAO.PutStorageItem(n.ContractID, []byte{prefixDomainPrice}, si); err != nil { + if err := n.nonfungible.Initialize(ic); err != nil { + return err + } + if err := setIntWithKey(n.ContractID, ic.DAO, []byte{prefixDomainPrice}, DefaultDomainPrice); err != nil { return err } - roots := stringList{} return putSerializableToDAO(n.ContractID, ic.DAO, []byte{prefixRoots}, &roots) } diff --git a/pkg/core/native/nonfungible.go b/pkg/core/native/nonfungible.go index 36826506f..ba0d3e4b2 100644 --- a/pkg/core/native/nonfungible.go +++ b/pkg/core/native/nonfungible.go @@ -50,8 +50,6 @@ const ( var ( nftTotalSupplyKey = []byte{prefixNFTTotalSupply} - - intOne = big.NewInt(1) ) func newNonFungible(name string, id int32, symbol string, decimals byte) *nonfungible { @@ -120,6 +118,11 @@ func newNonFungible(name string, id int32, symbol string, decimals byte) *nonfun return n } +// Initialize implements interop.Contract interface. +func (n nonfungible) Initialize(ic *interop.Context) error { + return setIntWithKey(n.ContractID, ic.DAO, nftTotalSupplyKey, 0) +} + func (n *nonfungible) symbol(_ *interop.Context, _ []stackitem.Item) stackitem.Item { return stackitem.NewByteArray([]byte(n.tokenSymbol)) } @@ -135,7 +138,7 @@ func (n *nonfungible) totalSupply(ic *interop.Context, _ []stackitem.Item) stack func (n *nonfungible) TotalSupply(d dao.DAO) *big.Int { si := d.GetStorageItem(n.ContractID, nftTotalSupplyKey) if si == nil { - return big.NewInt(0) + panic(errors.New("total supply is not initialized")) } return bigint.FromBytes(si.Value) } diff --git a/pkg/core/native/notary.go b/pkg/core/native/notary.go index 0a27a5dec..9713ba4ca 100644 --- a/pkg/core/native/notary.go +++ b/pkg/core/native/notary.go @@ -108,6 +108,11 @@ func (n *Notary) Metadata() *interop.ContractMD { // Initialize initializes Notary native contract and implements Contract interface. func (n *Notary) Initialize(ic *interop.Context) error { + err := setIntWithKey(n.ContractID, ic.DAO, maxNotValidBeforeDeltaKey, defaultMaxNotValidBeforeDelta) + if err != nil { + return err + } + n.isValid = true n.maxNotValidBeforeDelta = defaultMaxNotValidBeforeDelta return nil @@ -166,7 +171,7 @@ func (n *Notary) PostPersist(ic *interop.Context) error { return nil } - n.maxNotValidBeforeDelta = getUint32WithKey(n.ContractID, ic.DAO, maxNotValidBeforeDeltaKey, defaultMaxNotValidBeforeDelta) + n.maxNotValidBeforeDelta = uint32(getIntWithKey(n.ContractID, ic.DAO, maxNotValidBeforeDeltaKey)) n.isValid = true return nil } @@ -379,7 +384,7 @@ func (n *Notary) GetMaxNotValidBeforeDelta(dao dao.DAO) uint32 { if n.isValid { return n.maxNotValidBeforeDelta } - return getUint32WithKey(n.ContractID, dao, maxNotValidBeforeDeltaKey, defaultMaxNotValidBeforeDelta) + return uint32(getIntWithKey(n.ContractID, dao, maxNotValidBeforeDeltaKey)) } // setMaxNotValidBeforeDelta is Notary contract method and sets the maximum NotValidBefore delta. @@ -393,7 +398,7 @@ func (n *Notary) setMaxNotValidBeforeDelta(ic *interop.Context, args []stackitem } n.lock.Lock() defer n.lock.Unlock() - err := setUint32WithKey(n.ContractID, ic.DAO, maxNotValidBeforeDeltaKey, value) + err := setIntWithKey(n.ContractID, ic.DAO, maxNotValidBeforeDeltaKey, int64(value)) if err != nil { panic(fmt.Errorf("failed to put value into the storage: %w", err)) } diff --git a/pkg/core/native/oracle.go b/pkg/core/native/oracle.go index ed775d7d4..2ef566f68 100644 --- a/pkg/core/native/oracle.go +++ b/pkg/core/native/oracle.go @@ -20,6 +20,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" + "github.com/nspcc-dev/neo-go/pkg/encoding/bigint" "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" @@ -201,8 +202,7 @@ func (o *Oracle) Metadata() *interop.ContractMD { // Initialize initializes Oracle contract. func (o *Oracle) Initialize(ic *interop.Context) error { - si := &state.StorageItem{Value: make([]byte, 8)} // uint64(0) LE - return ic.DAO.PutStorageItem(o.ContractID, prefixRequestID, si) + return setIntWithKey(o.ContractID, ic.DAO, prefixRequestID, 0) } func getResponse(tx *transaction.Transaction) *transaction.OracleResponse { @@ -302,8 +302,10 @@ func (o *Oracle) RequestInternal(ic *interop.Context, url string, filter *string callingHash := ic.VM.GetCallingScriptHash() o.GAS.mint(ic, o.Hash, gas, false) si := ic.DAO.GetStorageItem(o.ContractID, prefixRequestID) - id := binary.LittleEndian.Uint64(si.Value) + 1 - binary.LittleEndian.PutUint64(si.Value, id) + itemID := bigint.FromBytes(si.Value) + id := itemID.Uint64() + itemID.Add(itemID, intOne) + si.Value = bigint.ToPreallocatedBytes(itemID, si.Value) if err := ic.DAO.PutStorageItem(o.ContractID, prefixRequestID, si); err != nil { return err } diff --git a/pkg/core/native/policy.go b/pkg/core/native/policy.go index 4afdef5ce..79a9edf40 100644 --- a/pkg/core/native/policy.go +++ b/pkg/core/native/policy.go @@ -29,6 +29,9 @@ const ( defaultFeePerByte = 1000 defaultMaxVerificationGas = 50000000 defaultMaxBlockSystemFee = 9000 * GASFactor + // DefaultStoragePrice is the price to pay for 1 byte of storage. + DefaultStoragePrice = 100000 + // minBlockSystemFee is the minimum allowed system fee per block. minBlockSystemFee = 4007600 // maxExecFeeFactor is the maximum allowed execution fee factor. @@ -163,6 +166,25 @@ func (p *Policy) Metadata() *interop.ContractMD { // Initialize initializes Policy native contract and implements Contract interface. func (p *Policy) Initialize(ic *interop.Context) error { + if err := setIntWithKey(p.ContractID, ic.DAO, maxTransactionsPerBlockKey, defaultMaxTransactionsPerBlock); err != nil { + return err + } + if err := setIntWithKey(p.ContractID, ic.DAO, feePerByteKey, defaultFeePerByte); err != nil { + return err + } + if err := setIntWithKey(p.ContractID, ic.DAO, maxBlockSizeKey, defaultMaxBlockSize); err != nil { + return err + } + if err := setIntWithKey(p.ContractID, ic.DAO, maxBlockSystemFeeKey, defaultMaxBlockSystemFee); err != nil { + return err + } + if err := setIntWithKey(p.ContractID, ic.DAO, execFeeFactorKey, defaultExecFeeFactor); err != nil { + return err + } + if err := setIntWithKey(p.ContractID, ic.DAO, storagePriceKey, DefaultStoragePrice); err != nil { + return err + } + p.isValid = true p.maxTransactionsPerBlock = defaultMaxTransactionsPerBlock p.maxBlockSize = defaultMaxBlockSize @@ -170,7 +192,7 @@ func (p *Policy) Initialize(ic *interop.Context) error { p.feePerByte = defaultFeePerByte p.maxBlockSystemFee = defaultMaxBlockSystemFee p.maxVerificationGas = defaultMaxVerificationGas - p.storagePrice = StoragePrice + p.storagePrice = DefaultStoragePrice p.blockedAccounts = make([]util.Uint160, 0) return nil @@ -189,13 +211,13 @@ func (p *Policy) PostPersist(ic *interop.Context) error { return nil } - p.maxTransactionsPerBlock = getUint32WithKey(p.ContractID, ic.DAO, maxTransactionsPerBlockKey, defaultMaxTransactionsPerBlock) - p.maxBlockSize = getUint32WithKey(p.ContractID, ic.DAO, maxBlockSizeKey, defaultMaxBlockSize) - p.execFeeFactor = getUint32WithKey(p.ContractID, ic.DAO, execFeeFactorKey, defaultExecFeeFactor) - p.feePerByte = getInt64WithKey(p.ContractID, ic.DAO, feePerByteKey, defaultFeePerByte) - p.maxBlockSystemFee = getInt64WithKey(p.ContractID, ic.DAO, maxBlockSystemFeeKey, defaultMaxBlockSystemFee) + p.maxTransactionsPerBlock = uint32(getIntWithKey(p.ContractID, ic.DAO, maxTransactionsPerBlockKey)) + p.maxBlockSize = uint32(getIntWithKey(p.ContractID, ic.DAO, maxBlockSizeKey)) + p.execFeeFactor = uint32(getIntWithKey(p.ContractID, ic.DAO, execFeeFactorKey)) + p.feePerByte = getIntWithKey(p.ContractID, ic.DAO, feePerByteKey) + p.maxBlockSystemFee = getIntWithKey(p.ContractID, ic.DAO, maxBlockSystemFeeKey) p.maxVerificationGas = defaultMaxVerificationGas - p.storagePrice = getUint32WithKey(p.ContractID, ic.DAO, storagePriceKey, StoragePrice) + p.storagePrice = uint32(getIntWithKey(p.ContractID, ic.DAO, storagePriceKey)) p.blockedAccounts = make([]util.Uint160, 0) siMap, err := ic.DAO.GetStorageItemsWithPrefix(p.ContractID, []byte{blockedAccountPrefix}) @@ -231,7 +253,7 @@ func (p *Policy) GetMaxTransactionsPerBlockInternal(dao dao.DAO) uint32 { if p.isValid { return p.maxTransactionsPerBlock } - return getUint32WithKey(p.ContractID, dao, maxTransactionsPerBlockKey, defaultMaxTransactionsPerBlock) + return uint32(getIntWithKey(p.ContractID, dao, maxTransactionsPerBlockKey)) } // getMaxBlockSize is Policy contract method and returns maximum block size. @@ -246,7 +268,7 @@ func (p *Policy) GetMaxBlockSizeInternal(dao dao.DAO) uint32 { if p.isValid { return p.maxBlockSize } - return getUint32WithKey(p.ContractID, dao, maxBlockSizeKey, defaultMaxBlockSize) + return uint32(getIntWithKey(p.ContractID, dao, maxBlockSizeKey)) } // getFeePerByte is Policy contract method and returns required transaction's fee @@ -262,7 +284,7 @@ func (p *Policy) GetFeePerByteInternal(dao dao.DAO) int64 { if p.isValid { return p.feePerByte } - return getInt64WithKey(p.ContractID, dao, feePerByteKey, defaultFeePerByte) + return getIntWithKey(p.ContractID, dao, feePerByteKey) } // GetMaxVerificationGas returns maximum gas allowed to be burned during verificaion. @@ -286,7 +308,7 @@ func (p *Policy) GetMaxBlockSystemFeeInternal(dao dao.DAO) int64 { if p.isValid { return p.maxBlockSystemFee } - return getInt64WithKey(p.ContractID, dao, maxBlockSystemFeeKey, defaultMaxBlockSystemFee) + return getIntWithKey(p.ContractID, dao, maxBlockSystemFeeKey) } func (p *Policy) getExecFeeFactor(ic *interop.Context, _ []stackitem.Item) stackitem.Item { @@ -300,7 +322,7 @@ func (p *Policy) GetExecFeeFactorInternal(d dao.DAO) int64 { if p.isValid { return int64(p.execFeeFactor) } - return int64(getUint32WithKey(p.ContractID, d, execFeeFactorKey, defaultExecFeeFactor)) + return getIntWithKey(p.ContractID, d, execFeeFactorKey) } func (p *Policy) setExecFeeFactor(ic *interop.Context, args []stackitem.Item) stackitem.Item { @@ -313,7 +335,7 @@ func (p *Policy) setExecFeeFactor(ic *interop.Context, args []stackitem.Item) st } p.lock.Lock() defer p.lock.Unlock() - err := setUint32WithKey(p.ContractID, ic.DAO, execFeeFactorKey, uint32(value)) + err := setIntWithKey(p.ContractID, ic.DAO, execFeeFactorKey, int64(value)) if err != nil { panic(err) } @@ -356,7 +378,7 @@ func (p *Policy) GetStoragePriceInternal(d dao.DAO) int64 { if p.isValid { return int64(p.storagePrice) } - return int64(getUint32WithKey(p.ContractID, d, storagePriceKey, StoragePrice)) + return getIntWithKey(p.ContractID, d, storagePriceKey) } func (p *Policy) setStoragePrice(ic *interop.Context, args []stackitem.Item) stackitem.Item { @@ -369,7 +391,7 @@ func (p *Policy) setStoragePrice(ic *interop.Context, args []stackitem.Item) sta } p.lock.Lock() defer p.lock.Unlock() - err := setUint32WithKey(p.ContractID, ic.DAO, storagePriceKey, uint32(value)) + err := setIntWithKey(p.ContractID, ic.DAO, storagePriceKey, int64(value)) if err != nil { panic(err) } @@ -389,7 +411,7 @@ func (p *Policy) setMaxTransactionsPerBlock(ic *interop.Context, args []stackite } p.lock.Lock() defer p.lock.Unlock() - err := setUint32WithKey(p.ContractID, ic.DAO, maxTransactionsPerBlockKey, value) + err := setIntWithKey(p.ContractID, ic.DAO, maxTransactionsPerBlockKey, int64(value)) if err != nil { panic(err) } @@ -408,7 +430,7 @@ func (p *Policy) setMaxBlockSize(ic *interop.Context, args []stackitem.Item) sta } p.lock.Lock() defer p.lock.Unlock() - err := setUint32WithKey(p.ContractID, ic.DAO, maxBlockSizeKey, value) + err := setIntWithKey(p.ContractID, ic.DAO, maxBlockSizeKey, int64(value)) if err != nil { panic(err) } @@ -427,7 +449,7 @@ func (p *Policy) setFeePerByte(ic *interop.Context, args []stackitem.Item) stack } p.lock.Lock() defer p.lock.Unlock() - err := setInt64WithKey(p.ContractID, ic.DAO, feePerByteKey, value) + err := setIntWithKey(p.ContractID, ic.DAO, feePerByteKey, value) if err != nil { panic(err) } @@ -446,7 +468,7 @@ func (p *Policy) setMaxBlockSystemFee(ic *interop.Context, args []stackitem.Item } p.lock.Lock() defer p.lock.Unlock() - err := setInt64WithKey(p.ContractID, ic.DAO, maxBlockSystemFeeKey, value) + err := setIntWithKey(p.ContractID, ic.DAO, maxBlockSystemFeeKey, value) if err != nil { panic(err) } diff --git a/pkg/core/native/util.go b/pkg/core/native/util.go index 929b3d1e3..30d5e9e8a 100644 --- a/pkg/core/native/util.go +++ b/pkg/core/native/util.go @@ -2,15 +2,21 @@ package native import ( "encoding/binary" + "encoding/hex" + "fmt" + "math/big" "github.com/nspcc-dev/neo-go/pkg/core/dao" "github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/storage" + "github.com/nspcc-dev/neo-go/pkg/encoding/bigint" "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" ) +var intOne = big.NewInt(1) + func getSerializableFromDAO(id int32, d dao.DAO, key []byte, item io.Serializable) error { si := d.GetStorageItem(id, key) if si == nil { @@ -64,6 +70,20 @@ func setUint32WithKey(id int32, dao dao.DAO, key []byte, value uint32) error { return dao.PutStorageItem(id, key, si) } +func setIntWithKey(id int32, dao dao.DAO, key []byte, value int64) error { + si := &state.StorageItem{Value: bigint.ToBytes(big.NewInt(value))} + return dao.PutStorageItem(id, key, si) +} + +func getIntWithKey(id int32, dao dao.DAO, key []byte) int64 { + si := dao.GetStorageItem(id, key) + if si == nil { + panic(fmt.Errorf("item with id = %d and key = %s is not initialized", id, hex.EncodeToString(key))) + + } + return bigint.FromBytes(si.Value).Int64() +} + // makeUint160Key creates a key from account script hash. func makeUint160Key(prefix byte, h util.Uint160) []byte { k := make([]byte, util.Uint160Size+1) diff --git a/pkg/core/native_oracle_test.go b/pkg/core/native_oracle_test.go index b6ac58d64..a99aa2c76 100644 --- a/pkg/core/native_oracle_test.go +++ b/pkg/core/native_oracle_test.go @@ -124,7 +124,7 @@ func TestOracle_Request(t *testing.T) { userData := []byte("custom info") txHash := putOracleRequest(t, cs.Hash, bc, "url", &filter, "handle", userData, gasForResponse) - req, err := orc.GetRequestInternal(bc.dao, 1) + req, err := orc.GetRequestInternal(bc.dao, 0) require.NotNil(t, req) require.NoError(t, err) require.Equal(t, txHash, req.OriginalTxID) @@ -136,7 +136,7 @@ func TestOracle_Request(t *testing.T) { idList, err := orc.GetIDListInternal(bc.dao, "url") require.NoError(t, err) - require.Equal(t, &native.IDList{1}, idList) + require.Equal(t, &native.IDList{0}, idList) // Finish. priv, err := keys.NewPrivateKey() @@ -161,7 +161,7 @@ func TestOracle_Request(t *testing.T) { require.True(t, errors.Is(err, native.ErrResponseNotFound), "got: %v", err) resp := &transaction.OracleResponse{ - ID: 13, + ID: 12, Code: transaction.Success, Result: []byte{4, 8, 15, 16, 23, 42}, } @@ -173,7 +173,7 @@ func TestOracle_Request(t *testing.T) { require.True(t, errors.Is(err, native.ErrRequestNotFound), "got: %v", err) // We need to ensure that callback is called thus, executing full script is necessary. - resp.ID = 1 + resp.ID = 0 ic.VM.LoadScriptWithFlags(tx.Script, callflag.All) require.NoError(t, ic.VM.Run()) @@ -189,18 +189,18 @@ func TestOracle_Request(t *testing.T) { require.Equal(t, resp.Result, arr[3].Value()) // Check that processed request is removed during `postPersist`. - _, err = orc.GetRequestInternal(ic.DAO, 1) + _, err = orc.GetRequestInternal(ic.DAO, 0) require.NoError(t, err) require.NoError(t, orc.PostPersist(ic)) - _, err = orc.GetRequestInternal(ic.DAO, 1) + _, err = orc.GetRequestInternal(ic.DAO, 0) require.Error(t, err) t.Run("ErrorOnFinish", func(t *testing.T) { - const reqID = 2 + const reqID = 1 putOracleRequest(t, cs.Hash, bc, "url", nil, "handle", []byte{1, 2}, gasForResponse) - _, err := orc.GetRequestInternal(bc.dao, reqID) // ensure ID is 2 + _, err := orc.GetRequestInternal(bc.dao, reqID) // ensure ID is 1 require.NoError(t, err) tx = transaction.New(netmode.UnitTestNet, orc.GetOracleResponseScript(), 0) diff --git a/pkg/core/native_policy_test.go b/pkg/core/native_policy_test.go index 6745db604..3ef5c4828 100644 --- a/pkg/core/native_policy_test.go +++ b/pkg/core/native_policy_test.go @@ -142,10 +142,10 @@ func TestStoragePrice(t *testing.T) { t.Run("get, internal method", func(t *testing.T) { n := chain.contracts.Policy.GetStoragePriceInternal(chain.dao) - require.Equal(t, int64(native.StoragePrice), n) + require.Equal(t, int64(native.DefaultStoragePrice), n) }) - testGetSet(t, chain, chain.contracts.Policy.Hash, "StoragePrice", native.StoragePrice, 1, 10000000) + testGetSet(t, chain, chain.contracts.Policy.Hash, "StoragePrice", native.DefaultStoragePrice, 1, 10000000) } func TestBlockedAccounts(t *testing.T) { diff --git a/pkg/core/oracle_test.go b/pkg/core/oracle_test.go index 45f55ca46..8545bf3fa 100644 --- a/pkg/core/oracle_test.go +++ b/pkg/core/oracle_test.go @@ -165,26 +165,26 @@ func TestOracle(t *testing.T) { t.Run("NormalRequest", func(t *testing.T) { resp := &transaction.OracleResponse{ - ID: 1, + ID: 0, Code: transaction.Success, Result: []byte{1, 2, 3, 4}, } - req := checkResp(t, 1, resp) + req := checkResp(t, 0, resp) - reqs := map[uint64]*state.OracleRequest{1: req} + reqs := map[uint64]*state.OracleRequest{0: req} orc2.ProcessRequestsInternal(reqs) - require.Equal(t, resp, m2[1].resp) + require.Equal(t, resp, m2[0].resp) require.Empty(t, ch2) t.Run("InvalidSignature", func(t *testing.T) { - orc1.AddResponse(acc2.PrivateKey().PublicKey(), m2[1].resp.ID, []byte{1, 2, 3}) + orc1.AddResponse(acc2.PrivateKey().PublicKey(), m2[0].resp.ID, []byte{1, 2, 3}) require.Empty(t, ch1) }) - orc1.AddResponse(acc2.PrivateKey().PublicKey(), m2[1].resp.ID, m2[1].txSig) + orc1.AddResponse(acc2.PrivateKey().PublicKey(), m2[0].resp.ID, m2[0].txSig) checkEmitTx(t, ch1) t.Run("FirstOtherThenMe", func(t *testing.T) { - const reqID = 2 + const reqID = 1 resp := &transaction.OracleResponse{ ID: reqID, @@ -203,58 +203,58 @@ func TestOracle(t *testing.T) { }) t.Run("Invalid", func(t *testing.T) { t.Run("Timeout", func(t *testing.T) { - checkResp(t, 3, &transaction.OracleResponse{ - ID: 3, + checkResp(t, 2, &transaction.OracleResponse{ + ID: 2, Code: transaction.Timeout, }) }) t.Run("NotFound", func(t *testing.T) { - checkResp(t, 4, &transaction.OracleResponse{ - ID: 4, + checkResp(t, 3, &transaction.OracleResponse{ + ID: 3, Code: transaction.NotFound, }) }) t.Run("Forbidden", func(t *testing.T) { + checkResp(t, 4, &transaction.OracleResponse{ + ID: 4, + Code: transaction.Forbidden, + }) + }) + t.Run("PrivateNetwork", func(t *testing.T) { checkResp(t, 5, &transaction.OracleResponse{ ID: 5, Code: transaction.Forbidden, }) }) - t.Run("PrivateNetwork", func(t *testing.T) { + t.Run("Big", func(t *testing.T) { checkResp(t, 6, &transaction.OracleResponse{ ID: 6, - Code: transaction.Forbidden, - }) - }) - t.Run("Big", func(t *testing.T) { - checkResp(t, 7, &transaction.OracleResponse{ - ID: 7, Code: transaction.ResponseTooLarge, }) }) t.Run("MaxAllowedSmallGAS", func(t *testing.T) { - checkResp(t, 8, &transaction.OracleResponse{ - ID: 8, + checkResp(t, 7, &transaction.OracleResponse{ + ID: 7, Code: transaction.InsufficientFunds, }) }) }) t.Run("MaxAllowedEnoughGAS", func(t *testing.T) { - checkResp(t, 9, &transaction.OracleResponse{ - ID: 9, + checkResp(t, 8, &transaction.OracleResponse{ + ID: 8, Code: transaction.Success, Result: make([]byte, transaction.MaxOracleResultSize), }) }) t.Run("WithFilter", func(t *testing.T) { - checkResp(t, 10, &transaction.OracleResponse{ - ID: 10, + checkResp(t, 9, &transaction.OracleResponse{ + ID: 9, Code: transaction.Success, Result: []byte(`[2]`), }) t.Run("invalid response", func(t *testing.T) { - checkResp(t, 11, &transaction.OracleResponse{ - ID: 11, + checkResp(t, 10, &transaction.OracleResponse{ + ID: 10, Code: transaction.Error, }) })