core: store initial native values into DAO
This commit is contained in:
parent
641896b2fb
commit
260bcd373c
14 changed files with 147 additions and 88 deletions
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
})
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue