Merge pull request #1724 from nspcc-dev/rpc/getnative

Implement `getnativecontracts` RPC
This commit is contained in:
Roman Khimov 2021-02-11 14:43:09 +03:00 committed by GitHub
commit 2ee755e09f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 320 additions and 220 deletions

View file

@ -85,6 +85,11 @@ func (*FakeChain) IsExtensibleAllowed(uint160 util.Uint160) bool {
return true
}
// GetNatives implements blockchainer.Blockchainer interface.
func (*FakeChain) GetNatives() []state.NativeContract {
panic("TODO")
}
// GetNotaryDepositExpiration implements Blockchainer interface.
func (chain *FakeChain) GetNotaryDepositExpiration(acc util.Uint160) uint32 {
if chain.NotaryDepositExpiration != 0 {

View file

@ -166,17 +166,21 @@ func TestAppCall(t *testing.T) {
innerNef, err := nef.NewFile(inner)
require.NoError(t, err)
return &state.Contract{
Hash: ih,
NEF: *innerNef,
Manifest: *m,
ContractBase: state.ContractBase{
Hash: ih,
NEF: *innerNef,
Manifest: *m,
},
}, nil
} else if h.Equals(barH) {
barNef, err := nef.NewFile(barCtr)
require.NoError(t, err)
return &state.Contract{
Hash: barH,
NEF: *barNef,
Manifest: *mBar,
ContractBase: state.ContractBase{
Hash: barH,
NEF: *barNef,
Manifest: *mBar,
},
}, nil
}
return nil, errors.New("not found")

View file

@ -920,7 +920,7 @@ func (bc *Blockchain) processNEP17Transfer(cache *dao.Cached, h util.Uint256, b
var id int32
nativeContract := bc.contracts.ByHash(sc)
if nativeContract != nil {
id = nativeContract.Metadata().ContractID
id = nativeContract.Metadata().ID
} else {
assetContract, err := bc.contracts.Management.GetContract(cache, sc)
if err != nil {
@ -1018,7 +1018,7 @@ func (bc *Blockchain) GetUtilityTokenBalance(acc util.Uint160) *big.Int {
if err != nil {
return big.NewInt(0)
}
balance := bs.Trackers[bc.contracts.GAS.ContractID].Balance
balance := bs.Trackers[bc.contracts.GAS.ID].Balance
return &balance
}
@ -1029,7 +1029,7 @@ func (bc *Blockchain) GetGoverningTokenBalance(acc util.Uint160) (*big.Int, uint
if err != nil {
return big.NewInt(0), 0
}
neo := bs.Trackers[bc.contracts.NEO.ContractID]
neo := bs.Trackers[bc.contracts.NEO.ID]
return &neo.Balance, neo.LastUpdatedBlock
}
@ -1243,6 +1243,15 @@ func (bc *Blockchain) GetNativeContractScriptHash(name string) (util.Uint160, er
return util.Uint160{}, errors.New("Unknown native contract")
}
// GetNatives returns list of native contracts.
func (bc *Blockchain) GetNatives() []state.NativeContract {
res := make([]state.NativeContract, 0, len(bc.contracts.Contracts))
for _, c := range bc.contracts.Contracts {
res = append(res, c.Metadata().NativeContract)
}
return res
}
// GetConfig returns the config stored in the blockchain.
func (bc *Blockchain) GetConfig() config.ProtocolConfiguration {
return bc.config

View file

@ -45,6 +45,7 @@ type Blockchainer interface {
GetAppExecResults(util.Uint256, trigger.Type) ([]state.AppExecResult, error)
GetNotaryDepositExpiration(acc util.Uint160) uint32
GetNativeContractScriptHash(string) (util.Uint160, error)
GetNatives() []state.NativeContract
GetNextBlockValidators() ([]*keys.PublicKey, error)
GetNEP17Balances(util.Uint160) *state.NEP17Balances
GetNotaryContractScriptHash() util.Uint160

View file

@ -589,7 +589,7 @@ func checkFAULTState(t *testing.T, result *state.AppExecResult) {
}
func checkBalanceOf(t *testing.T, chain *Blockchain, addr util.Uint160, expected int) {
balance := chain.GetNEP17Balances(addr).Trackers[chain.contracts.GAS.ContractID]
balance := chain.GetNEP17Balances(addr).Trackers[chain.contracts.GAS.ID]
require.Equal(t, int64(expected), balance.Balance.Int64())
}

View file

@ -99,12 +99,9 @@ type Contract interface {
// ContractMD represents native contract instance.
type ContractMD struct {
Manifest manifest.Manifest
Name string
ContractID int32
NEF nef.File
Hash util.Uint160
Methods map[MethodAndArgCount]MethodAndPrice
state.NativeContract
Name string
Methods map[MethodAndArgCount]MethodAndPrice
}
// MethodAndArgCount represents method's signature.
@ -116,11 +113,12 @@ type MethodAndArgCount struct {
// NewContractMD returns Contract with the specified list of methods.
func NewContractMD(name string, id int32) *ContractMD {
c := &ContractMD{
Name: name,
ContractID: id,
Methods: make(map[MethodAndArgCount]MethodAndPrice),
Name: name,
Methods: make(map[MethodAndArgCount]MethodAndPrice),
}
c.ID = id
// NEF is now stored in contract state and affects state dump.
// Therefore values are taken from C# node.
c.NEF.Header.Compiler = "neo-core-v3.0"

View file

@ -262,10 +262,12 @@ func createVMAndContractState(t *testing.T) (*vm.VM, *state.Contract, *interop.C
ne, err := nef.NewFile(script)
require.NoError(t, err)
contractState := &state.Contract{
NEF: *ne,
Hash: hash.Hash160(script),
Manifest: *m,
ID: 123,
ContractBase: state.ContractBase{
NEF: *ne,
Hash: hash.Hash160(script),
Manifest: *m,
ID: 123,
},
}
chain := newTestChain(t)

View file

@ -68,7 +68,8 @@ func TestContractIsStandard(t *testing.T) {
pub := priv.PublicKey()
ne, err := nef.NewFile(pub.GetVerificationScript())
require.NoError(t, err)
err = chain.contracts.Management.PutContractState(ic.DAO, &state.Contract{ID: 42, Hash: pub.GetScriptHash(), NEF: *ne})
err = chain.contracts.Management.PutContractState(ic.DAO,
&state.Contract{ContractBase: state.ContractBase{ID: 42, Hash: pub.GetScriptHash(), NEF: *ne}})
require.NoError(t, err)
v.Estack().PushVal(pub.GetScriptHash().BytesBE())
@ -79,7 +80,8 @@ func TestContractIsStandard(t *testing.T) {
script := []byte{byte(opcode.PUSHT)}
ne, err := nef.NewFile(script)
require.NoError(t, err)
require.NoError(t, chain.contracts.Management.PutContractState(ic.DAO, &state.Contract{ID: 24, Hash: hash.Hash160(script), NEF: *ne}))
require.NoError(t, chain.contracts.Management.PutContractState(ic.DAO,
&state.Contract{ContractBase: state.ContractBase{ID: 24, Hash: hash.Hash160(script), NEF: *ne}}))
v.Estack().PushVal(crypto.Hash160(script).BytesBE())
require.NoError(t, contractIsStandard(ic))
@ -540,9 +542,11 @@ func getTestContractState(bc *Blockchain) (*state.Contract, *state.Contract) {
m.Permissions[1].Methods.Add("method")
cs := &state.Contract{
Hash: h,
Manifest: *m,
ID: 42,
ContractBase: state.ContractBase{
Hash: h,
Manifest: *m,
ID: 42,
},
}
ne, err := nef.NewFile(script)
if err != nil {
@ -582,10 +586,12 @@ func getTestContractState(bc *Blockchain) (*state.Contract, *state.Contract) {
}
return cs, &state.Contract{
NEF: *ne,
Hash: hash.Hash160(currScript),
Manifest: *m,
ID: 123,
ContractBase: state.ContractBase{
NEF: *ne,
Hash: hash.Hash160(currScript),
Manifest: *m,
ID: 123,
},
}
}
@ -906,11 +912,13 @@ func TestRuntimeCheckWitness(t *testing.T) {
ne, err := nef.NewFile(contractScript)
require.NoError(t, err)
contractState := &state.Contract{
ID: 15,
Hash: contractScriptHash,
NEF: *ne,
Manifest: manifest.Manifest{
Groups: []manifest.Group{{PublicKey: pk.PublicKey(), Signature: make([]byte, keys.SignatureLen)}},
ContractBase: state.ContractBase{
ID: 15,
Hash: contractScriptHash,
NEF: *ne,
Manifest: manifest.Manifest{
Groups: []manifest.Group{{PublicKey: pk.PublicKey(), Signature: make([]byte, keys.SignatureLen)}},
},
},
}
require.NoError(t, bc.contracts.Management.PutContractState(ic.DAO, contractState))

View file

@ -242,7 +242,7 @@ func (s *Designate) GetDesignatedByRole(d dao.DAO, r Role, index uint32) (keys.P
return val.nodes.Copy(), val.height, nil
}
}
kvs, err := d.GetStorageItemsWithPrefix(s.ContractID, []byte{byte(r)})
kvs, err := d.GetStorageItemsWithPrefix(s.ID, []byte{byte(r)})
if err != nil {
return nil, 0, err
}
@ -309,14 +309,14 @@ func (s *Designate) DesignateAsRole(ic *interop.Context, r Role, pubs keys.Publi
key[0] = byte(r)
binary.BigEndian.PutUint32(key[1:], ic.Block.Index+1)
si := ic.DAO.GetStorageItem(s.ContractID, key)
si := ic.DAO.GetStorageItem(s.ID, key)
if si != nil {
return ErrAlreadyDesignated
}
sort.Sort(pubs)
s.rolesChangedFlag.Store(true)
si = &state.StorageItem{Value: NodeList(pubs).Bytes()}
return ic.DAO.PutStorageItem(s.ContractID, key, si)
return ic.DAO.PutStorageItem(s.ID, key, si)
}
func (s *Designate) getRole(item stackitem.Item) (Role, bool) {

View file

@ -15,7 +15,7 @@ func Call(ic *interop.Context) error {
id := int32(ic.VM.Estack().Pop().BigInt().Int64())
var c interop.Contract
for _, ctr := range ic.Natives {
if ctr.Metadata().ContractID == id {
if ctr.Metadata().ID == id {
c = ctr
break
}

View file

@ -151,7 +151,7 @@ func (m *Management) GetContract(d dao.DAO, hash util.Uint160) (*state.Contract,
func (m *Management) getContractFromDAO(d dao.DAO, hash util.Uint160) (*state.Contract, error) {
contract := new(state.Contract)
key := makeContractKey(hash)
err := getSerializableFromDAO(m.ContractID, d, key, contract)
err := getSerializableFromDAO(m.ID, d, key, contract)
if err != nil {
return nil, err
}
@ -263,7 +263,7 @@ func (m *Management) markUpdated(h util.Uint160) {
func (m *Management) Deploy(d dao.DAO, sender util.Uint160, neff *nef.File, manif *manifest.Manifest) (*state.Contract, error) {
h := state.CreateContractHash(sender, neff.Checksum, manif.Name)
key := makeContractKey(h)
si := d.GetStorageItem(m.ContractID, key)
si := d.GetStorageItem(m.ID, key)
if si != nil {
return nil, errors.New("contract already exists")
}
@ -280,10 +280,12 @@ func (m *Management) Deploy(d dao.DAO, sender util.Uint160, neff *nef.File, mani
return nil, err
}
newcontract := &state.Contract{
ID: id,
Hash: h,
NEF: *neff,
Manifest: *manif,
ContractBase: state.ContractBase{
ID: id,
Hash: h,
NEF: *neff,
Manifest: *manif,
},
}
err = m.PutContractState(d, newcontract)
if err != nil {
@ -371,7 +373,7 @@ func (m *Management) Destroy(d dao.DAO, hash util.Uint160) error {
return err
}
key := makeContractKey(hash)
err = d.DeleteStorageItem(m.ContractID, key)
err = d.DeleteStorageItem(m.ID, key)
if err != nil {
return err
}
@ -399,7 +401,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 getIntWithKey(m.ContractID, dao, keyMinimumDeploymentFee)
return getIntWithKey(m.ID, dao, keyMinimumDeploymentFee)
}
func (m *Management) setMinimumDeploymentFee(ic *interop.Context, args []stackitem.Item) stackitem.Item {
@ -410,7 +412,7 @@ func (m *Management) setMinimumDeploymentFee(ic *interop.Context, args []stackit
if !m.NEO.checkCommittee(ic) {
panic("invalid committee signature")
}
err := setIntWithKey(m.ContractID, ic.DAO, keyMinimumDeploymentFee, int64(value))
err := setIntWithKey(m.ID, ic.DAO, keyMinimumDeploymentFee, int64(value))
if err != nil {
panic(err)
}
@ -451,10 +453,7 @@ func (m *Management) OnPersist(ic *interop.Context) error {
md := native.Metadata()
cs := &state.Contract{
ID: md.ContractID,
Hash: md.Hash,
NEF: md.NEF,
Manifest: md.Manifest,
ContractBase: md.ContractBase,
}
err := m.PutContractState(ic.DAO, cs)
if err != nil {
@ -479,7 +478,7 @@ func (m *Management) InitializeCache(d dao.DAO) error {
defer m.mtx.Unlock()
var initErr error
d.Seek(m.ContractID, []byte{prefixContract}, func(_, v []byte) {
d.Seek(m.ID, []byte{prefixContract}, func(_, v []byte) {
var r = io.NewBinReaderFromBuf(v)
var si state.StorageItem
si.DecodeBinary(r)
@ -521,16 +520,16 @@ func (m *Management) PostPersist(ic *interop.Context) error {
// Initialize implements Contract interface.
func (m *Management) Initialize(ic *interop.Context) error {
if err := setIntWithKey(m.ContractID, ic.DAO, keyMinimumDeploymentFee, defaultMinimumDeploymentFee); err != nil {
if err := setIntWithKey(m.ID, ic.DAO, keyMinimumDeploymentFee, defaultMinimumDeploymentFee); err != nil {
return err
}
return setIntWithKey(m.ContractID, ic.DAO, keyNextAvailableID, 1)
return setIntWithKey(m.ID, ic.DAO, keyNextAvailableID, 1)
}
// PutContractState saves given contract state into given DAO.
func (m *Management) PutContractState(d dao.DAO, cs *state.Contract) error {
key := makeContractKey(cs.Hash)
if err := putSerializableToDAO(m.ContractID, d, key, cs); err != nil {
if err := putSerializableToDAO(m.ID, d, key, cs); err != nil {
return err
}
m.markUpdated(cs.Hash)
@ -541,7 +540,7 @@ func (m *Management) PutContractState(d dao.DAO, cs *state.Contract) error {
}
func (m *Management) getNextContractID(d dao.DAO) (int32, error) {
si := d.GetStorageItem(m.ContractID, keyNextAvailableID)
si := d.GetStorageItem(m.ID, keyNextAvailableID)
if si == nil {
return 0, errors.New("nextAvailableID is not initialized")
@ -550,7 +549,7 @@ func (m *Management) getNextContractID(d dao.DAO) (int32, error) {
ret := int32(id.Int64())
id.Add(id, intOne)
si.Value = bigint.ToPreallocatedBytes(id, si.Value)
return ret, d.PutStorageItem(m.ContractID, keyNextAvailableID, si)
return ret, d.PutStorageItem(m.ID, keyNextAvailableID, si)
}
func (m *Management) emitNotification(ic *interop.Context, name string, hash util.Uint160) {

View file

@ -79,7 +79,7 @@ func TestManagement_Initialize(t *testing.T) {
t.Run("invalid contract state", func(t *testing.T) {
d := dao.NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet, false)
mgmt := newManagement()
require.NoError(t, d.PutStorageItem(mgmt.ContractID, []byte{prefixContract}, &state.StorageItem{Value: []byte{0xFF}}))
require.NoError(t, d.PutStorageItem(mgmt.ID, []byte{prefixContract}, &state.StorageItem{Value: []byte{0xFF}}))
require.Error(t, mgmt.InitializeCache(d))
})
}

View file

@ -175,18 +175,18 @@ func (n *NameService) Initialize(ic *interop.Context) error {
if err := n.nonfungible.Initialize(ic); err != nil {
return err
}
if err := setIntWithKey(n.ContractID, ic.DAO, []byte{prefixDomainPrice}, DefaultDomainPrice); err != nil {
if err := setIntWithKey(n.ID, ic.DAO, []byte{prefixDomainPrice}, DefaultDomainPrice); err != nil {
return err
}
roots := stringList{}
return putSerializableToDAO(n.ContractID, ic.DAO, []byte{prefixRoots}, &roots)
return putSerializableToDAO(n.ID, ic.DAO, []byte{prefixRoots}, &roots)
}
// OnPersist implements interop.Contract interface.
func (n *NameService) OnPersist(ic *interop.Context) error {
now := uint32(ic.Block.Timestamp/1000 + 1)
keys := []string{}
ic.DAO.Seek(n.ContractID, []byte{prefixExpiration}, func(k, v []byte) {
ic.DAO.Seek(n.ID, []byte{prefixExpiration}, func(k, v []byte) {
if binary.BigEndian.Uint32(k) >= now {
return
}
@ -200,20 +200,20 @@ func (n *NameService) OnPersist(ic *interop.Context) error {
for i := range keys {
key[0] = prefixExpiration
key = append(key[:1], []byte(keys[i])...)
if err := ic.DAO.DeleteStorageItem(n.ContractID, key); err != nil {
if err := ic.DAO.DeleteStorageItem(n.ID, key); err != nil {
return err
}
keysToRemove = keysToRemove[:0]
key[0] = prefixRecord
key = append(key[:1], keys[i][4:]...)
ic.DAO.Seek(n.ContractID, key, func(k, v []byte) {
ic.DAO.Seek(n.ID, key, func(k, v []byte) {
keysToRemove = append(keysToRemove, k)
})
for i := range keysToRemove {
keyRecord = append(keyRecord[:0], key...)
keyRecord = append(keyRecord, keysToRemove[i]...)
err := ic.DAO.DeleteStorageItem(n.ContractID, keyRecord)
err := ic.DAO.DeleteStorageItem(n.ID, keyRecord)
if err != nil {
return err
}
@ -242,7 +242,7 @@ func (n *NameService) addRoot(ic *interop.Context, args []stackitem.Item) stacki
panic("name already exists")
}
err := putSerializableToDAO(n.ContractID, ic.DAO, []byte{prefixRoots}, &roots)
err := putSerializableToDAO(n.ID, ic.DAO, []byte{prefixRoots}, &roots)
if err != nil {
panic(err)
}
@ -259,7 +259,7 @@ func (n *NameService) setPrice(ic *interop.Context, args []stackitem.Item) stack
n.checkCommittee(ic)
si := &state.StorageItem{Value: bigint.ToBytes(price)}
err := ic.DAO.PutStorageItem(n.ContractID, []byte{prefixDomainPrice}, si)
err := ic.DAO.PutStorageItem(n.ID, []byte{prefixDomainPrice}, si)
if err != nil {
panic(err)
}
@ -271,7 +271,7 @@ func (n *NameService) getPrice(ic *interop.Context, _ []stackitem.Item) stackite
}
func (n *NameService) getPriceInternal(d dao.DAO) *big.Int {
si := d.GetStorageItem(n.ContractID, []byte{prefixDomainPrice})
si := d.GetStorageItem(n.ID, []byte{prefixDomainPrice})
return bigint.FromBytes(si.Value)
}
@ -286,7 +286,7 @@ func (n *NameService) parseName(item stackitem.Item) (string, []string, []byte)
func (n *NameService) isAvailable(ic *interop.Context, args []stackitem.Item) stackitem.Item {
_, names, key := n.parseName(args[0])
if ic.DAO.GetStorageItem(n.ContractID, key) != nil {
if ic.DAO.GetStorageItem(n.ID, key) != nil {
return stackitem.NewBool(false)
}
@ -300,7 +300,7 @@ func (n *NameService) isAvailable(ic *interop.Context, args []stackitem.Item) st
func (n *NameService) getRootsInternal(d dao.DAO) (stringList, bool) {
var sl stringList
err := getSerializableFromDAO(n.ContractID, d, []byte{prefixRoots}, &sl)
err := getSerializableFromDAO(n.ID, d, []byte{prefixRoots}, &sl)
if err != nil {
// Roots are being stored in `Initialize()` and thus must always be present.
panic(err)
@ -315,7 +315,7 @@ func (n *NameService) register(ic *interop.Context, args []stackitem.Item) stack
panic("owner is not witnessed")
}
if ic.DAO.GetStorageItem(n.ContractID, key) != nil {
if ic.DAO.GetStorageItem(n.ID, key) != nil {
return stackitem.NewBool(false)
}
@ -334,7 +334,7 @@ func (n *NameService) register(ic *interop.Context, args []stackitem.Item) stack
Expiration: uint32(ic.Block.Timestamp/1000 + secondsInYear),
}
n.mint(ic, token)
err := ic.DAO.PutStorageItem(n.ContractID,
err := ic.DAO.PutStorageItem(n.ID,
makeExpirationKey(token.Expiration, token.ID()),
&state.StorageItem{Value: []byte{0}})
if err != nil {
@ -349,25 +349,25 @@ func (n *NameService) renew(ic *interop.Context, args []stackitem.Item) stackite
panic("insufficient gas")
}
token := new(nameState)
err := getSerializableFromDAO(n.ContractID, ic.DAO, key, token)
err := getSerializableFromDAO(n.ID, ic.DAO, key, token)
if err != nil {
panic(err)
}
keyExpiration := makeExpirationKey(token.Expiration, token.ID())
if err := ic.DAO.DeleteStorageItem(n.ContractID, keyExpiration); err != nil {
if err := ic.DAO.DeleteStorageItem(n.ID, keyExpiration); err != nil {
panic(err)
}
token.Expiration += secondsInYear
err = putSerializableToDAO(n.ContractID, ic.DAO, key, token)
err = putSerializableToDAO(n.ID, ic.DAO, key, token)
if err != nil {
panic(err)
}
binary.BigEndian.PutUint32(key[1:], token.Expiration)
si := &state.StorageItem{Value: []byte{0}}
err = ic.DAO.PutStorageItem(n.ContractID, key, si)
err = ic.DAO.PutStorageItem(n.ID, key, si)
if err != nil {
panic(err)
}
@ -388,7 +388,7 @@ func (n *NameService) setAdmin(ic *interop.Context, args []stackitem.Item) stack
}
token := new(nameState)
err := getSerializableFromDAO(n.ContractID, ic.DAO, key, token)
err := getSerializableFromDAO(n.ID, ic.DAO, key, token)
if err != nil {
panic(err)
}
@ -397,7 +397,7 @@ func (n *NameService) setAdmin(ic *interop.Context, args []stackitem.Item) stack
}
token.HasAdmin = !isNull
token.Admin = admin
err = putSerializableToDAO(n.ContractID, ic.DAO, key, token)
err = putSerializableToDAO(n.ID, ic.DAO, key, token)
if err != nil {
panic(err)
}
@ -441,7 +441,7 @@ func (n *NameService) setRecord(ic *interop.Context, args []stackitem.Item) stac
}
key := makeRecordKey(domain, name, rt)
si := &state.StorageItem{Value: []byte(data)}
if err := ic.DAO.PutStorageItem(n.ContractID, key, si); err != nil {
if err := ic.DAO.PutStorageItem(n.ID, key, si); err != nil {
panic(err)
}
return stackitem.Null{}
@ -473,7 +473,7 @@ func (n *NameService) getRecord(ic *interop.Context, args []stackitem.Item) stac
domain := toDomain(name)
rt := toRecordType(args[1])
key := makeRecordKey(domain, name, rt)
si := ic.DAO.GetStorageItem(n.ContractID, key)
si := ic.DAO.GetStorageItem(n.ID, key)
if si == nil {
return stackitem.Null{}
}
@ -486,7 +486,7 @@ func (n *NameService) deleteRecord(ic *interop.Context, args []stackitem.Item) s
domain := toDomain(name)
key := n.getTokenKey([]byte(domain))
token := new(nameState)
err := getSerializableFromDAO(n.ContractID, ic.DAO, key, token)
err := getSerializableFromDAO(n.ID, ic.DAO, key, token)
if err != nil {
panic(err)
}
@ -496,7 +496,7 @@ func (n *NameService) deleteRecord(ic *interop.Context, args []stackitem.Item) s
}
key = makeRecordKey(domain, name, rt)
if err := ic.DAO.DeleteStorageItem(n.ContractID, key); err != nil {
if err := ic.DAO.DeleteStorageItem(n.ID, key); err != nil {
panic(err)
}
return stackitem.Null{}
@ -532,7 +532,7 @@ func (n *NameService) getRecordsInternal(d dao.DAO, name string) map[RecordType]
key := makeRecordKey(domain, name, 0)
key = key[:len(key)-1]
res := make(map[RecordType]string)
d.Seek(n.ContractID, key, func(k, v []byte) {
d.Seek(n.ID, key, func(k, v []byte) {
rt := RecordType(k[len(k)-1])
var si state.StorageItem
r := io.NewBinReaderFromBuf(v)

View file

@ -170,7 +170,7 @@ func (n *NEO) Initialize(ic *interop.Context) error {
return err
}
err = ic.DAO.PutStorageItem(n.ContractID, prefixCommittee, &state.StorageItem{Value: cvs.Bytes()})
err = ic.DAO.PutStorageItem(n.ID, prefixCommittee, &state.StorageItem{Value: cvs.Bytes()})
if err != nil {
return err
}
@ -190,7 +190,7 @@ func (n *NEO) Initialize(ic *interop.Context) error {
gr := &gasRecord{{Index: index, GASPerBlock: *value}}
n.gasPerBlock.Store(*gr)
n.gasPerBlockChanged.Store(false)
err = ic.DAO.PutStorageItem(n.ContractID, []byte{prefixVotersCount}, &state.StorageItem{Value: []byte{}})
err = ic.DAO.PutStorageItem(n.ID, []byte{prefixVotersCount}, &state.StorageItem{Value: []byte{}})
if err != nil {
return err
}
@ -203,7 +203,7 @@ func (n *NEO) Initialize(ic *interop.Context) error {
// called only when deploying native contracts.
func (n *NEO) InitializeCache(bc blockchainer.Blockchainer, d dao.DAO) error {
var committee = keysWithVotes{}
si := d.GetStorageItem(n.ContractID, prefixCommittee)
si := d.GetStorageItem(n.ID, prefixCommittee)
if err := committee.DecodeBytes(si.Value); err != nil {
return err
}
@ -243,7 +243,7 @@ func (n *NEO) updateCommittee(ic *interop.Context) error {
// We need to put in storage anyway, as it affects dumps
committee := n.committee.Load().(keysWithVotes)
si := &state.StorageItem{Value: committee.Bytes()}
return ic.DAO.PutStorageItem(n.ContractID, prefixCommittee, si)
return ic.DAO.PutStorageItem(n.ID, prefixCommittee, si)
}
_, cvs, err := n.computeCommitteeMembers(ic.Chain, ic.DAO)
@ -255,7 +255,7 @@ func (n *NEO) updateCommittee(ic *interop.Context) error {
}
n.votesChanged.Store(false)
si := &state.StorageItem{Value: cvs.Bytes()}
return ic.DAO.PutStorageItem(n.ContractID, prefixCommittee, si)
return ic.DAO.PutStorageItem(n.ID, prefixCommittee, si)
}
// ShouldUpdateCommittee returns true if committee is updated at block h.
@ -311,7 +311,7 @@ func (n *NEO) PostPersist(ic *interop.Context) error {
binary.BigEndian.PutUint32(key[34:], ic.Block.Index+1)
si.Value = bigint.ToBytes(tmp)
if err := ic.DAO.PutStorageItem(n.ContractID, key, si); err != nil {
if err := ic.DAO.PutStorageItem(n.ID, key, si); err != nil {
return err
}
}
@ -333,7 +333,7 @@ func (n *NEO) getGASPerVote(d dao.DAO, key []byte, index ...uint32) []big.Int {
var max = make([]uint32, len(index))
var reward = make([]big.Int, len(index))
var si state.StorageItem
d.Seek(n.ContractID, key, func(k, v []byte) {
d.Seek(n.ID, key, func(k, v []byte) {
if len(k) == 4 {
num := binary.BigEndian.Uint32(k)
for i, ind := range index {
@ -413,7 +413,7 @@ func (n *NEO) getGASPerBlock(ic *interop.Context, _ []stackitem.Item) stackitem.
}
func (n *NEO) getSortedGASRecordFromDAO(d dao.DAO) (gasRecord, error) {
grMap, err := d.GetStorageItemsWithPrefix(n.ContractID, []byte{prefixGASPerBlock})
grMap, err := d.GetStorageItemsWithPrefix(n.ID, []byte{prefixGASPerBlock})
if err != nil {
return gasRecord{}, fmt.Errorf("failed to get gas records from storage: %w", err)
}
@ -495,16 +495,16 @@ func (n *NEO) dropCandidateIfZero(d dao.DAO, pub *keys.PublicKey, c *candidate)
if c.Registered || c.Votes.Sign() != 0 {
return false, nil
}
if err := d.DeleteStorageItem(n.ContractID, makeValidatorKey(pub)); err != nil {
if err := d.DeleteStorageItem(n.ID, makeValidatorKey(pub)); err != nil {
return true, err
}
var toRemove []string
d.Seek(n.ContractID, makeVoterKey(pub.Bytes()), func(k, v []byte) {
d.Seek(n.ID, makeVoterKey(pub.Bytes()), func(k, v []byte) {
toRemove = append(toRemove, string(k))
})
for i := range toRemove {
if err := d.DeleteStorageItem(n.ContractID, []byte(toRemove[i])); err != nil {
if err := d.DeleteStorageItem(n.ID, []byte(toRemove[i])); err != nil {
return true, err
}
}
@ -527,7 +527,7 @@ func makeVoterKey(pub []byte, prealloc ...[]byte) []byte {
// and having voted for active committee member.
func (n *NEO) CalculateBonus(d dao.DAO, acc util.Uint160, end uint32) (*big.Int, error) {
key := makeAccountKey(acc)
si := d.GetStorageItem(n.ContractID, key)
si := d.GetStorageItem(n.ID, key)
if si == nil {
return nil, storage.ErrKeyNotFound
}
@ -608,7 +608,7 @@ func (n *NEO) registerCandidate(ic *interop.Context, args []stackitem.Item) stac
// RegisterCandidateInternal registers pub as a new candidate.
func (n *NEO) RegisterCandidateInternal(ic *interop.Context, pub *keys.PublicKey) error {
key := makeValidatorKey(pub)
si := ic.DAO.GetStorageItem(n.ContractID, key)
si := ic.DAO.GetStorageItem(n.ID, key)
if si == nil {
c := &candidate{Registered: true}
si = &state.StorageItem{Value: c.Bytes()}
@ -617,7 +617,7 @@ func (n *NEO) RegisterCandidateInternal(ic *interop.Context, pub *keys.PublicKey
c.Registered = true
si.Value = c.Bytes()
}
return ic.DAO.PutStorageItem(n.ContractID, key, si)
return ic.DAO.PutStorageItem(n.ID, key, si)
}
func (n *NEO) unregisterCandidate(ic *interop.Context, args []stackitem.Item) stackitem.Item {
@ -635,7 +635,7 @@ func (n *NEO) unregisterCandidate(ic *interop.Context, args []stackitem.Item) st
// UnregisterCandidateInternal unregisters pub as a candidate.
func (n *NEO) UnregisterCandidateInternal(ic *interop.Context, pub *keys.PublicKey) error {
key := makeValidatorKey(pub)
si := ic.DAO.GetStorageItem(n.ContractID, key)
si := ic.DAO.GetStorageItem(n.ID, key)
if si == nil {
return nil
}
@ -647,7 +647,7 @@ func (n *NEO) UnregisterCandidateInternal(ic *interop.Context, pub *keys.PublicK
return err
}
si.Value = c.Bytes()
return ic.DAO.PutStorageItem(n.ContractID, key, si)
return ic.DAO.PutStorageItem(n.ID, key, si)
}
func (n *NEO) vote(ic *interop.Context, args []stackitem.Item) stackitem.Item {
@ -669,7 +669,7 @@ func (n *NEO) VoteInternal(ic *interop.Context, h util.Uint160, pub *keys.Public
return errors.New("invalid signature")
}
key := makeAccountKey(h)
si := ic.DAO.GetStorageItem(n.ContractID, key)
si := ic.DAO.GetStorageItem(n.ID, key)
if si == nil {
return errors.New("invalid account")
}
@ -697,7 +697,7 @@ func (n *NEO) VoteInternal(ic *interop.Context, h util.Uint160, pub *keys.Public
return err
}
si.Value = acc.Bytes()
return ic.DAO.PutStorageItem(n.ContractID, key, si)
return ic.DAO.PutStorageItem(n.ID, key, si)
}
// ModifyAccountVotes modifies votes of the specified account by value (can be negative).
@ -706,7 +706,7 @@ func (n *NEO) ModifyAccountVotes(acc *state.NEOBalanceState, d dao.DAO, value *b
n.votesChanged.Store(true)
if acc.VoteTo != nil {
key := makeValidatorKey(acc.VoteTo)
si := d.GetStorageItem(n.ContractID, key)
si := d.GetStorageItem(n.ID, key)
if si == nil {
return errors.New("invalid validator")
}
@ -722,13 +722,13 @@ func (n *NEO) ModifyAccountVotes(acc *state.NEOBalanceState, d dao.DAO, value *b
}
n.validators.Store(keys.PublicKeys(nil))
si.Value = cd.Bytes()
return d.PutStorageItem(n.ContractID, key, si)
return d.PutStorageItem(n.ID, key, si)
}
return nil
}
func (n *NEO) getCandidates(d dao.DAO, sortByKey bool) ([]keyWithVotes, error) {
siMap, err := d.GetStorageItemsWithPrefix(n.ContractID, []byte{prefixCandidate})
siMap, err := d.GetStorageItemsWithPrefix(n.ID, []byte{prefixCandidate})
if err != nil {
return nil, err
}
@ -811,14 +811,14 @@ func (n *NEO) getCommittee(ic *interop.Context, _ []stackitem.Item) stackitem.It
func (n *NEO) modifyVoterTurnout(d dao.DAO, amount *big.Int) error {
key := []byte{prefixVotersCount}
si := d.GetStorageItem(n.ContractID, key)
si := d.GetStorageItem(n.ID, key)
if si == nil {
return errors.New("voters count not found")
}
votersCount := bigint.FromBytes(si.Value)
votersCount.Add(votersCount, amount)
si.Value = bigint.ToBytes(votersCount)
return d.PutStorageItem(n.ContractID, key, si)
return d.PutStorageItem(n.ID, key, si)
}
// GetCommitteeMembers returns public keys of nodes in committee using cached value.
@ -848,7 +848,7 @@ func toKeysWithVotes(pubs keys.PublicKeys) keysWithVotes {
// computeCommitteeMembers returns public keys of nodes in committee.
func (n *NEO) computeCommitteeMembers(bc blockchainer.Blockchainer, d dao.DAO) (keys.PublicKeys, keysWithVotes, error) {
key := []byte{prefixVotersCount}
si := d.GetStorageItem(n.ContractID, key)
si := d.GetStorageItem(n.ID, key)
if si == nil {
return nil, nil, errors.New("voters count not found")
}
@ -928,5 +928,5 @@ func (n *NEO) putGASRecord(dao dao.DAO, index uint32, value *big.Int) error {
Value: bigint.ToBytes(value),
IsConst: false,
}
return dao.PutStorageItem(n.ContractID, key, si)
return dao.PutStorageItem(n.ID, key, si)
}

View file

@ -96,7 +96,7 @@ func (c *nep17TokenNative) TotalSupply(ic *interop.Context, _ []stackitem.Item)
}
func (c *nep17TokenNative) getTotalSupply(d dao.DAO) *big.Int {
si := d.GetStorageItem(c.ContractID, totalSupplyKey)
si := d.GetStorageItem(c.ID, totalSupplyKey)
if si == nil {
return big.NewInt(0)
}
@ -105,7 +105,7 @@ func (c *nep17TokenNative) getTotalSupply(d dao.DAO) *big.Int {
func (c *nep17TokenNative) saveTotalSupply(d dao.DAO, supply *big.Int) error {
si := &state.StorageItem{Value: bigint.ToBytes(supply)}
return d.PutStorageItem(c.ContractID, totalSupplyKey, si)
return d.PutStorageItem(c.ID, totalSupplyKey, si)
}
func (c *nep17TokenNative) Transfer(ic *interop.Context, args []stackitem.Item) stackitem.Item {
@ -163,7 +163,7 @@ func (c *nep17TokenNative) emitTransfer(ic *interop.Context, from, to *util.Uint
func (c *nep17TokenNative) updateAccBalance(ic *interop.Context, acc util.Uint160, amount *big.Int) error {
key := makeAccountKey(acc)
si := ic.DAO.GetStorageItem(c.ContractID, key)
si := ic.DAO.GetStorageItem(c.ID, key)
if si == nil {
if amount.Sign() <= 0 {
return errors.New("insufficient funds")
@ -176,9 +176,9 @@ func (c *nep17TokenNative) updateAccBalance(ic *interop.Context, acc util.Uint16
return err
}
if si.Value == nil {
err = ic.DAO.DeleteStorageItem(c.ContractID, key)
err = ic.DAO.DeleteStorageItem(c.ID, key)
} else {
err = ic.DAO.PutStorageItem(c.ContractID, key, si)
err = ic.DAO.PutStorageItem(c.ID, key, si)
}
return err
}
@ -225,7 +225,7 @@ func (c *nep17TokenNative) balanceOf(ic *interop.Context, args []stackitem.Item)
if err != nil {
panic(err)
}
balance := bs.Trackers[c.ContractID].Balance
balance := bs.Trackers[c.ID].Balance
return stackitem.NewBigInteger(&balance)
}
@ -251,14 +251,14 @@ func (c *nep17TokenNative) addTokens(ic *interop.Context, h util.Uint160, amount
}
key := makeAccountKey(h)
si := ic.DAO.GetStorageItem(c.ContractID, key)
si := ic.DAO.GetStorageItem(c.ID, key)
if si == nil {
si = new(state.StorageItem)
}
if err := c.incBalance(ic, h, si, amount); err != nil {
panic(err)
}
if err := ic.DAO.PutStorageItem(c.ContractID, key, si); err != nil {
if err := ic.DAO.PutStorageItem(c.ID, key, si); err != nil {
panic(err)
}

View file

@ -121,7 +121,7 @@ func newNonFungible(name string, id int32, symbol string, decimals byte) *nonfun
// Initialize implements interop.Contract interface.
func (n nonfungible) Initialize(ic *interop.Context) error {
return setIntWithKey(n.ContractID, ic.DAO, nftTotalSupplyKey, 0)
return setIntWithKey(n.ID, ic.DAO, nftTotalSupplyKey, 0)
}
func (n *nonfungible) symbol(_ *interop.Context, _ []stackitem.Item) stackitem.Item {
@ -137,7 +137,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)
si := d.GetStorageItem(n.ID, nftTotalSupplyKey)
if si == nil {
panic(errors.New("total supply is not initialized"))
}
@ -146,7 +146,7 @@ func (n *nonfungible) TotalSupply(d dao.DAO) *big.Int {
func (n *nonfungible) setTotalSupply(d dao.DAO, ts *big.Int) {
si := &state.StorageItem{Value: bigint.ToBytes(ts)}
err := d.PutStorageItem(n.ContractID, nftTotalSupplyKey, si)
err := d.PutStorageItem(n.ID, nftTotalSupplyKey, si)
if err != nil {
panic(err)
}
@ -155,23 +155,23 @@ func (n *nonfungible) setTotalSupply(d dao.DAO, ts *big.Int) {
func (n *nonfungible) tokenState(d dao.DAO, tokenID []byte) (nftTokenState, []byte, error) {
key := n.getTokenKey(tokenID)
s := n.newTokenState()
err := getSerializableFromDAO(n.ContractID, d, key, s)
err := getSerializableFromDAO(n.ID, d, key, s)
return s, key, err
}
func (n *nonfungible) accountState(d dao.DAO, owner util.Uint160) (*state.NFTAccountState, []byte, error) {
acc := new(state.NFTAccountState)
keyAcc := makeNFTAccountKey(owner)
err := getSerializableFromDAO(n.ContractID, d, keyAcc, acc)
err := getSerializableFromDAO(n.ID, d, keyAcc, acc)
return acc, keyAcc, err
}
func (n *nonfungible) putAccountState(d dao.DAO, key []byte, acc *state.NFTAccountState) {
var err error
if acc.Balance.Sign() == 0 {
err = d.DeleteStorageItem(n.ContractID, key)
err = d.DeleteStorageItem(n.ID, key)
} else {
err = putSerializableToDAO(n.ContractID, d, key, acc)
err = putSerializableToDAO(n.ID, d, key, acc)
}
if err != nil {
panic(err)
@ -216,7 +216,7 @@ func (n *nonfungible) BalanceOf(ic *interop.Context, args []stackitem.Item) stac
func (n *nonfungible) tokens(ic *interop.Context, args []stackitem.Item) stackitem.Item {
prefix := []byte{prefixNFTToken}
siMap, err := ic.DAO.GetStorageItemsWithPrefix(n.ContractID, prefix)
siMap, err := ic.DAO.GetStorageItemsWithPrefix(n.ID, prefix)
if err != nil {
panic(err)
}
@ -248,10 +248,10 @@ func (n *nonfungible) tokensOf(ic *interop.Context, args []stackitem.Item) stack
func (n *nonfungible) mint(ic *interop.Context, s nftTokenState) {
key := n.getTokenKey(s.ID())
if ic.DAO.GetStorageItem(n.ContractID, key) != nil {
if ic.DAO.GetStorageItem(n.ID, key) != nil {
panic("token is already minted")
}
if err := putSerializableToDAO(n.ContractID, ic.DAO, key, s); err != nil {
if err := putSerializableToDAO(n.ID, ic.DAO, key, s); err != nil {
panic(err)
}
@ -310,11 +310,11 @@ func (n *nonfungible) burn(ic *interop.Context, tokenID []byte) {
func (n *nonfungible) burnByKey(ic *interop.Context, key []byte) {
token := n.newTokenState()
err := getSerializableFromDAO(n.ContractID, ic.DAO, key, token)
err := getSerializableFromDAO(n.ID, ic.DAO, key, token)
if err != nil {
panic(err)
}
if err := ic.DAO.DeleteStorageItem(n.ContractID, key); err != nil {
if err := ic.DAO.DeleteStorageItem(n.ID, key); err != nil {
panic(err)
}
@ -361,7 +361,7 @@ func (n *nonfungible) transfer(ic *interop.Context, args []stackitem.Item) stack
token.Base().Owner = to
n.onTransferred(token)
err = putSerializableToDAO(n.ContractID, ic.DAO, tokenKey, token)
err = putSerializableToDAO(n.ID, ic.DAO, tokenKey, token)
if err != nil {
panic(err)
}

View file

@ -108,7 +108,7 @@ 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)
err := setIntWithKey(n.ID, ic.DAO, maxNotValidBeforeDeltaKey, defaultMaxNotValidBeforeDelta)
if err != nil {
return err
}
@ -171,7 +171,7 @@ func (n *Notary) PostPersist(ic *interop.Context) error {
return nil
}
n.maxNotValidBeforeDelta = uint32(getIntWithKey(n.ContractID, ic.DAO, maxNotValidBeforeDeltaKey))
n.maxNotValidBeforeDelta = uint32(getIntWithKey(n.ID, ic.DAO, maxNotValidBeforeDeltaKey))
n.isValid = true
return nil
}
@ -384,7 +384,7 @@ func (n *Notary) GetMaxNotValidBeforeDelta(dao dao.DAO) uint32 {
if n.isValid {
return n.maxNotValidBeforeDelta
}
return uint32(getIntWithKey(n.ContractID, dao, maxNotValidBeforeDeltaKey))
return uint32(getIntWithKey(n.ID, dao, maxNotValidBeforeDeltaKey))
}
// setMaxNotValidBeforeDelta is Notary contract method and sets the maximum NotValidBefore delta.
@ -398,7 +398,7 @@ func (n *Notary) setMaxNotValidBeforeDelta(ic *interop.Context, args []stackitem
}
n.lock.Lock()
defer n.lock.Unlock()
err := setIntWithKey(n.ContractID, ic.DAO, maxNotValidBeforeDeltaKey, int64(value))
err := setIntWithKey(n.ID, ic.DAO, maxNotValidBeforeDeltaKey, int64(value))
if err != nil {
panic(fmt.Errorf("failed to put value into the storage: %w", err))
}
@ -411,7 +411,7 @@ func (n *Notary) setMaxNotValidBeforeDelta(ic *interop.Context, args []stackitem
func (n *Notary) GetDepositFor(dao dao.DAO, acc util.Uint160) *state.Deposit {
key := append([]byte{prefixDeposit}, acc.BytesBE()...)
deposit := new(state.Deposit)
err := getSerializableFromDAO(n.ContractID, dao, key, deposit)
err := getSerializableFromDAO(n.ID, dao, key, deposit)
if err == nil {
return deposit
}
@ -424,13 +424,13 @@ func (n *Notary) GetDepositFor(dao dao.DAO, acc util.Uint160) *state.Deposit {
// putDepositFor puts deposit on the balance of the specified account in the storage.
func (n *Notary) putDepositFor(dao dao.DAO, deposit *state.Deposit, acc util.Uint160) error {
key := append([]byte{prefixDeposit}, acc.BytesBE()...)
return putSerializableToDAO(n.ContractID, dao, key, deposit)
return putSerializableToDAO(n.ID, dao, key, deposit)
}
// removeDepositFor removes deposit from the storage.
func (n *Notary) removeDepositFor(dao dao.DAO, acc util.Uint160) error {
key := append([]byte{prefixDeposit}, acc.BytesBE()...)
return dao.DeleteStorageItem(n.ContractID, key)
return dao.DeleteStorageItem(n.ID, key)
}
// calculateNotaryReward calculates the reward for a single notary node based on FEE's count and Notary nodes count.

View file

@ -145,7 +145,7 @@ func (o *Oracle) PostPersist(ic *interop.Context) error {
if err := o.getSerializableFromDAO(ic.DAO, reqKey, req); err != nil {
continue
}
if err := ic.DAO.DeleteStorageItem(o.ContractID, reqKey); err != nil {
if err := ic.DAO.DeleteStorageItem(o.ID, reqKey); err != nil {
return err
}
if orc != nil {
@ -163,10 +163,10 @@ func (o *Oracle) PostPersist(ic *interop.Context) error {
var err error
if len(*idList) == 0 {
err = ic.DAO.DeleteStorageItem(o.ContractID, idKey)
err = ic.DAO.DeleteStorageItem(o.ID, idKey)
} else {
si := &state.StorageItem{Value: idList.Bytes()}
err = ic.DAO.PutStorageItem(o.ContractID, idKey, si)
err = ic.DAO.PutStorageItem(o.ID, idKey, si)
}
if err != nil {
return err
@ -202,7 +202,7 @@ func (o *Oracle) Metadata() *interop.ContractMD {
// Initialize initializes Oracle contract.
func (o *Oracle) Initialize(ic *interop.Context) error {
return setIntWithKey(o.ContractID, ic.DAO, prefixRequestID, 0)
return setIntWithKey(o.ID, ic.DAO, prefixRequestID, 0)
}
func getResponse(tx *transaction.Transaction) *transaction.OracleResponse {
@ -301,12 +301,12 @@ 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)
si := ic.DAO.GetStorageItem(o.ID, prefixRequestID)
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 {
if err := ic.DAO.PutStorageItem(o.ID, prefixRequestID, si); err != nil {
return err
}
@ -358,7 +358,7 @@ func (o *Oracle) RequestInternal(ic *interop.Context, url string, filter *string
func (o *Oracle) PutRequestInternal(id uint64, req *state.OracleRequest, d dao.DAO) error {
reqItem := &state.StorageItem{Value: req.Bytes()}
reqKey := makeRequestKey(id)
if err := d.PutStorageItem(o.ContractID, reqKey, reqItem); err != nil {
if err := d.PutStorageItem(o.ID, reqKey, reqItem); err != nil {
return err
}
o.newRequests[id] = req
@ -374,7 +374,7 @@ func (o *Oracle) PutRequestInternal(id uint64, req *state.OracleRequest, d dao.D
}
*lst = append(*lst, id)
si := &state.StorageItem{Value: lst.Bytes()}
return d.PutStorageItem(o.ContractID, key, si)
return d.PutStorageItem(o.ID, key, si)
}
// GetScriptHash returns script hash or oracle nodes.
@ -419,7 +419,7 @@ func (o *Oracle) getOriginalTxID(d dao.DAO, tx *transaction.Transaction) util.Ui
// getRequests returns all requests which have not been finished yet.
func (o *Oracle) getRequests(d dao.DAO) (map[uint64]*state.OracleRequest, error) {
m, err := d.GetStorageItemsWithPrefix(o.ContractID, prefixRequest)
m, err := d.GetStorageItemsWithPrefix(o.ID, prefixRequest)
if err != nil {
return nil, err
}
@ -452,7 +452,7 @@ func makeIDListKey(url string) []byte {
}
func (o *Oracle) getSerializableFromDAO(d dao.DAO, key []byte, item io.Serializable) error {
return getSerializableFromDAO(o.ContractID, d, key, item)
return getSerializableFromDAO(o.ID, d, key, item)
}
// updateCache updates cached Oracle values if they've been changed
@ -466,7 +466,7 @@ func (o *Oracle) updateCache(d dao.DAO) error {
o.newRequests = make(map[uint64]*state.OracleRequest)
for id := range reqs {
key := makeRequestKey(id)
if si := d.GetStorageItem(o.ContractID, key); si == nil { // tx has failed
if si := d.GetStorageItem(o.ID, key); si == nil { // tx has failed
delete(reqs, id)
}
}

View file

@ -166,22 +166,22 @@ 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 {
if err := setIntWithKey(p.ID, ic.DAO, maxTransactionsPerBlockKey, defaultMaxTransactionsPerBlock); err != nil {
return err
}
if err := setIntWithKey(p.ContractID, ic.DAO, feePerByteKey, defaultFeePerByte); err != nil {
if err := setIntWithKey(p.ID, ic.DAO, feePerByteKey, defaultFeePerByte); err != nil {
return err
}
if err := setIntWithKey(p.ContractID, ic.DAO, maxBlockSizeKey, defaultMaxBlockSize); err != nil {
if err := setIntWithKey(p.ID, ic.DAO, maxBlockSizeKey, defaultMaxBlockSize); err != nil {
return err
}
if err := setIntWithKey(p.ContractID, ic.DAO, maxBlockSystemFeeKey, defaultMaxBlockSystemFee); err != nil {
if err := setIntWithKey(p.ID, ic.DAO, maxBlockSystemFeeKey, defaultMaxBlockSystemFee); err != nil {
return err
}
if err := setIntWithKey(p.ContractID, ic.DAO, execFeeFactorKey, defaultExecFeeFactor); err != nil {
if err := setIntWithKey(p.ID, ic.DAO, execFeeFactorKey, defaultExecFeeFactor); err != nil {
return err
}
if err := setIntWithKey(p.ContractID, ic.DAO, storagePriceKey, DefaultStoragePrice); err != nil {
if err := setIntWithKey(p.ID, ic.DAO, storagePriceKey, DefaultStoragePrice); err != nil {
return err
}
@ -211,16 +211,16 @@ func (p *Policy) PostPersist(ic *interop.Context) error {
return nil
}
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.maxTransactionsPerBlock = uint32(getIntWithKey(p.ID, ic.DAO, maxTransactionsPerBlockKey))
p.maxBlockSize = uint32(getIntWithKey(p.ID, ic.DAO, maxBlockSizeKey))
p.execFeeFactor = uint32(getIntWithKey(p.ID, ic.DAO, execFeeFactorKey))
p.feePerByte = getIntWithKey(p.ID, ic.DAO, feePerByteKey)
p.maxBlockSystemFee = getIntWithKey(p.ID, ic.DAO, maxBlockSystemFeeKey)
p.maxVerificationGas = defaultMaxVerificationGas
p.storagePrice = uint32(getIntWithKey(p.ContractID, ic.DAO, storagePriceKey))
p.storagePrice = uint32(getIntWithKey(p.ID, ic.DAO, storagePriceKey))
p.blockedAccounts = make([]util.Uint160, 0)
siMap, err := ic.DAO.GetStorageItemsWithPrefix(p.ContractID, []byte{blockedAccountPrefix})
siMap, err := ic.DAO.GetStorageItemsWithPrefix(p.ID, []byte{blockedAccountPrefix})
if err != nil {
return fmt.Errorf("failed to get blocked accounts from storage: %w", err)
}
@ -253,7 +253,7 @@ func (p *Policy) GetMaxTransactionsPerBlockInternal(dao dao.DAO) uint32 {
if p.isValid {
return p.maxTransactionsPerBlock
}
return uint32(getIntWithKey(p.ContractID, dao, maxTransactionsPerBlockKey))
return uint32(getIntWithKey(p.ID, dao, maxTransactionsPerBlockKey))
}
// getMaxBlockSize is Policy contract method and returns maximum block size.
@ -268,7 +268,7 @@ func (p *Policy) GetMaxBlockSizeInternal(dao dao.DAO) uint32 {
if p.isValid {
return p.maxBlockSize
}
return uint32(getIntWithKey(p.ContractID, dao, maxBlockSizeKey))
return uint32(getIntWithKey(p.ID, dao, maxBlockSizeKey))
}
// getFeePerByte is Policy contract method and returns required transaction's fee
@ -284,7 +284,7 @@ func (p *Policy) GetFeePerByteInternal(dao dao.DAO) int64 {
if p.isValid {
return p.feePerByte
}
return getIntWithKey(p.ContractID, dao, feePerByteKey)
return getIntWithKey(p.ID, dao, feePerByteKey)
}
// GetMaxVerificationGas returns maximum gas allowed to be burned during verificaion.
@ -308,7 +308,7 @@ func (p *Policy) GetMaxBlockSystemFeeInternal(dao dao.DAO) int64 {
if p.isValid {
return p.maxBlockSystemFee
}
return getIntWithKey(p.ContractID, dao, maxBlockSystemFeeKey)
return getIntWithKey(p.ID, dao, maxBlockSystemFeeKey)
}
func (p *Policy) getExecFeeFactor(ic *interop.Context, _ []stackitem.Item) stackitem.Item {
@ -322,7 +322,7 @@ func (p *Policy) GetExecFeeFactorInternal(d dao.DAO) int64 {
if p.isValid {
return int64(p.execFeeFactor)
}
return getIntWithKey(p.ContractID, d, execFeeFactorKey)
return getIntWithKey(p.ID, d, execFeeFactorKey)
}
func (p *Policy) setExecFeeFactor(ic *interop.Context, args []stackitem.Item) stackitem.Item {
@ -335,7 +335,7 @@ func (p *Policy) setExecFeeFactor(ic *interop.Context, args []stackitem.Item) st
}
p.lock.Lock()
defer p.lock.Unlock()
err := setIntWithKey(p.ContractID, ic.DAO, execFeeFactorKey, int64(value))
err := setIntWithKey(p.ID, ic.DAO, execFeeFactorKey, int64(value))
if err != nil {
panic(err)
}
@ -364,7 +364,7 @@ func (p *Policy) IsBlockedInternal(dao dao.DAO, hash util.Uint160) bool {
return false
}
key := append([]byte{blockedAccountPrefix}, hash.BytesBE()...)
return dao.GetStorageItem(p.ContractID, key) != nil
return dao.GetStorageItem(p.ID, key) != nil
}
func (p *Policy) getStoragePrice(ic *interop.Context, _ []stackitem.Item) stackitem.Item {
@ -378,7 +378,7 @@ func (p *Policy) GetStoragePriceInternal(d dao.DAO) int64 {
if p.isValid {
return int64(p.storagePrice)
}
return getIntWithKey(p.ContractID, d, storagePriceKey)
return getIntWithKey(p.ID, d, storagePriceKey)
}
func (p *Policy) setStoragePrice(ic *interop.Context, args []stackitem.Item) stackitem.Item {
@ -391,7 +391,7 @@ func (p *Policy) setStoragePrice(ic *interop.Context, args []stackitem.Item) sta
}
p.lock.Lock()
defer p.lock.Unlock()
err := setIntWithKey(p.ContractID, ic.DAO, storagePriceKey, int64(value))
err := setIntWithKey(p.ID, ic.DAO, storagePriceKey, int64(value))
if err != nil {
panic(err)
}
@ -411,7 +411,7 @@ func (p *Policy) setMaxTransactionsPerBlock(ic *interop.Context, args []stackite
}
p.lock.Lock()
defer p.lock.Unlock()
err := setIntWithKey(p.ContractID, ic.DAO, maxTransactionsPerBlockKey, int64(value))
err := setIntWithKey(p.ID, ic.DAO, maxTransactionsPerBlockKey, int64(value))
if err != nil {
panic(err)
}
@ -430,7 +430,7 @@ func (p *Policy) setMaxBlockSize(ic *interop.Context, args []stackitem.Item) sta
}
p.lock.Lock()
defer p.lock.Unlock()
err := setIntWithKey(p.ContractID, ic.DAO, maxBlockSizeKey, int64(value))
err := setIntWithKey(p.ID, ic.DAO, maxBlockSizeKey, int64(value))
if err != nil {
panic(err)
}
@ -449,7 +449,7 @@ func (p *Policy) setFeePerByte(ic *interop.Context, args []stackitem.Item) stack
}
p.lock.Lock()
defer p.lock.Unlock()
err := setIntWithKey(p.ContractID, ic.DAO, feePerByteKey, value)
err := setIntWithKey(p.ID, ic.DAO, feePerByteKey, value)
if err != nil {
panic(err)
}
@ -468,7 +468,7 @@ func (p *Policy) setMaxBlockSystemFee(ic *interop.Context, args []stackitem.Item
}
p.lock.Lock()
defer p.lock.Unlock()
err := setIntWithKey(p.ContractID, ic.DAO, maxBlockSystemFeeKey, value)
err := setIntWithKey(p.ID, ic.DAO, maxBlockSystemFeeKey, value)
if err != nil {
panic(err)
}
@ -489,7 +489,7 @@ func (p *Policy) blockAccount(ic *interop.Context, args []stackitem.Item) stacki
key := append([]byte{blockedAccountPrefix}, hash.BytesBE()...)
p.lock.Lock()
defer p.lock.Unlock()
err := ic.DAO.PutStorageItem(p.ContractID, key, &state.StorageItem{
err := ic.DAO.PutStorageItem(p.ID, key, &state.StorageItem{
Value: []byte{},
})
if err != nil {
@ -512,7 +512,7 @@ func (p *Policy) unblockAccount(ic *interop.Context, args []stackitem.Item) stac
key := append([]byte{blockedAccountPrefix}, hash.BytesBE()...)
p.lock.Lock()
defer p.lock.Unlock()
err := ic.DAO.DeleteStorageItem(p.ContractID, key)
err := ic.DAO.DeleteStorageItem(p.ID, key)
if err != nil {
panic(err)
}

View file

@ -172,10 +172,12 @@ func TestNativeContract_Invoke(t *testing.T) {
chain.registerNative(tn)
err := chain.contracts.Management.PutContractState(chain.dao, &state.Contract{
ID: 1,
NEF: tn.meta.NEF,
Hash: tn.meta.Hash,
Manifest: tn.meta.Manifest,
ContractBase: state.ContractBase{
ID: 1,
NEF: tn.meta.NEF,
Hash: tn.meta.Hash,
Manifest: tn.meta.Manifest,
},
})
require.NoError(t, err)
@ -210,9 +212,11 @@ func TestNativeContract_InvokeInternal(t *testing.T) {
chain.registerNative(tn)
err := chain.contracts.Management.PutContractState(chain.dao, &state.Contract{
ID: 1,
NEF: tn.meta.NEF,
Manifest: tn.meta.Manifest,
ContractBase: state.ContractBase{
ID: 1,
NEF: tn.meta.NEF,
Manifest: tn.meta.Manifest,
},
})
require.NoError(t, err)
@ -236,7 +240,7 @@ func TestNativeContract_InvokeInternal(t *testing.T) {
v.Estack().PushVal(14)
v.Estack().PushVal(28)
v.Estack().PushVal("sum")
v.Estack().PushVal(tn.Metadata().ContractID)
v.Estack().PushVal(tn.Metadata().ID)
require.NoError(t, native.Call(ic))
@ -253,10 +257,12 @@ func TestNativeContract_InvokeOtherContract(t *testing.T) {
chain.registerNative(tn)
err := chain.contracts.Management.PutContractState(chain.dao, &state.Contract{
ID: 1,
Hash: tn.meta.Hash,
NEF: tn.meta.NEF,
Manifest: tn.meta.Manifest,
ContractBase: state.ContractBase{
ID: 1,
Hash: tn.meta.Hash,
NEF: tn.meta.NEF,
Manifest: tn.meta.Manifest,
},
})
require.NoError(t, err)

View file

@ -92,10 +92,12 @@ func getOracleContractState(h util.Uint160) *state.Contract {
panic(err)
}
return &state.Contract{
NEF: *ne,
Hash: hash.Hash160(script),
Manifest: *m,
ID: 42,
ContractBase: state.ContractBase{
NEF: *ne,
Hash: hash.Hash160(script),
Manifest: *m,
ID: 42,
},
}
}

View file

@ -18,11 +18,22 @@ import (
// Contract holds information about a smart contract in the NEO blockchain.
type Contract struct {
ID int32 `json:"id"`
UpdateCounter uint16 `json:"updatecounter"`
Hash util.Uint160 `json:"hash"`
NEF nef.File `json:"nef"`
Manifest manifest.Manifest `json:"manifest"`
ContractBase
UpdateCounter uint16 `json:"updatecounter"`
}
// ContractBase represents part shared by native and user-deployed contracts.
type ContractBase struct {
ID int32 `json:"id"`
Hash util.Uint160 `json:"hash"`
NEF nef.File `json:"nef"`
Manifest manifest.Manifest `json:"manifest"`
}
// NativeContract holds information about native contract.
type NativeContract struct {
ContractBase
ActiveBlockIndex uint32 `json:"activeblockindex"`
}
// DecodeBinary implements Serializable interface.

View file

@ -34,19 +34,21 @@ func TestEncodeDecodeContractState(t *testing.T) {
ReturnType: smartcontract.BoolType,
}}
contract := &Contract{
ID: 123,
UpdateCounter: 42,
Hash: h,
NEF: nef.File{
Header: nef.Header{
Magic: nef.Magic,
Compiler: "neo-go.test-test",
ContractBase: ContractBase{
ID: 123,
Hash: h,
NEF: nef.File{
Header: nef.Header{
Magic: nef.Magic,
Compiler: "neo-go.test-test",
},
Tokens: []nef.MethodToken{},
Script: script,
Checksum: 0,
},
Tokens: []nef.MethodToken{},
Script: script,
Checksum: 0,
Manifest: *m,
},
Manifest: *m,
}
contract.NEF.Checksum = contract.NEF.CalculateChecksum()

View file

@ -240,6 +240,18 @@ func (c *Client) getContractState(param interface{}) (*state.Contract, error) {
return resp, nil
}
// GetNativeContracts queries information about native contracts.
func (c *Client) GetNativeContracts() ([]state.NativeContract, error) {
var (
params = request.NewRawParams()
resp []state.NativeContract
)
if err := c.performRequest("getnativecontracts", params, &resp); err != nil {
return resp, err
}
return resp, nil
}
// GetNEP17Balances is a wrapper for getnep17balances RPC.
func (c *Client) GetNEP17Balances(address util.Uint160) (*result.NEP17Balances, error) {
params := request.NewRawParams(address.StringLE())

View file

@ -350,10 +350,12 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
}
m := manifest.NewManifest("Test")
cs := &state.Contract{
ID: 0,
Hash: hash.Hash160(script),
NEF: newTestNEF(script),
Manifest: *m,
ContractBase: state.ContractBase{
ID: 0,
Hash: hash.Hash160(script),
NEF: newTestNEF(script),
Manifest: *m,
},
}
return cs
},
@ -371,10 +373,12 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
}
m := manifest.NewManifest("Test")
cs := &state.Contract{
ID: 0,
Hash: hash.Hash160(script),
NEF: newTestNEF(script),
Manifest: *m,
ContractBase: state.ContractBase{
ID: 0,
Hash: hash.Hash160(script),
NEF: newTestNEF(script),
Manifest: *m,
},
}
return cs
},
@ -392,10 +396,12 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
}
m := manifest.NewManifest("Test")
cs := &state.Contract{
ID: 0,
Hash: hash.Hash160(script),
NEF: newTestNEF(script),
Manifest: *m,
ContractBase: state.ContractBase{
ID: 0,
Hash: hash.Hash160(script),
NEF: newTestNEF(script),
Manifest: *m,
},
}
return cs
},

View file

@ -322,3 +322,17 @@ func TestInvokeVerify(t *testing.T) {
require.False(t, res.Stack[0].Value().(bool))
})
}
func TestClient_GetNativeContracts(t *testing.T) {
chain, rpcSrv, httpSrv := initServerWithInMemoryChain(t)
defer chain.Close()
defer rpcSrv.Shutdown()
c, err := client.New(context.Background(), httpSrv.URL, client.Options{})
require.NoError(t, err)
require.NoError(t, c.Init())
cs, err := c.GetNativeContracts()
require.NoError(t, err)
require.Equal(t, chain.GetNatives(), cs)
}

View file

@ -103,6 +103,7 @@ var rpcHandlers = map[string]func(*Server, request.Params) (interface{}, *respon
"getcommittee": (*Server).getCommittee,
"getconnectioncount": (*Server).getConnectionCount,
"getcontractstate": (*Server).getContractState,
"getnativecontracts": (*Server).getNativeContracts,
"getnep17balances": (*Server).getNEP17Balances,
"getnep17transfers": (*Server).getNEP17Transfers,
"getpeers": (*Server).getPeers,
@ -986,6 +987,10 @@ func (s *Server) getContractState(reqParams request.Params) (interface{}, *respo
return cs, nil
}
func (s *Server) getNativeContracts(_ request.Params) (interface{}, *response.Error) {
return s.chain.GetNatives(), nil
}
// getBlockSysFee returns the system fees of the block, based on the specified index.
func (s *Server) getBlockSysFee(reqParams request.Params) (interface{}, *response.Error) {
param := reqParams.ValueWithType(0, request.NumberT)

View file

@ -552,6 +552,22 @@ var rpcTestCases = map[string][]rpcTestCase{
},
},
},
"getnativecontracts": {
{
params: "[]",
result: func(e *executor) interface{} {
return new([]state.NativeContract)
},
check: func(t *testing.T, e *executor, res interface{}) {
lst := res.(*[]state.NativeContract)
for i := range *lst {
cs := e.chain.GetContractState((*lst)[i].Hash)
require.NotNil(t, cs)
require.True(t, cs.ID <= 0)
}
},
},
},
"getpeers": {
{
params: "[]",