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 return true
} }
// GetNatives implements blockchainer.Blockchainer interface.
func (*FakeChain) GetNatives() []state.NativeContract {
panic("TODO")
}
// GetNotaryDepositExpiration implements Blockchainer interface. // GetNotaryDepositExpiration implements Blockchainer interface.
func (chain *FakeChain) GetNotaryDepositExpiration(acc util.Uint160) uint32 { func (chain *FakeChain) GetNotaryDepositExpiration(acc util.Uint160) uint32 {
if chain.NotaryDepositExpiration != 0 { if chain.NotaryDepositExpiration != 0 {

View file

@ -166,17 +166,21 @@ func TestAppCall(t *testing.T) {
innerNef, err := nef.NewFile(inner) innerNef, err := nef.NewFile(inner)
require.NoError(t, err) require.NoError(t, err)
return &state.Contract{ return &state.Contract{
ContractBase: state.ContractBase{
Hash: ih, Hash: ih,
NEF: *innerNef, NEF: *innerNef,
Manifest: *m, Manifest: *m,
},
}, nil }, nil
} else if h.Equals(barH) { } else if h.Equals(barH) {
barNef, err := nef.NewFile(barCtr) barNef, err := nef.NewFile(barCtr)
require.NoError(t, err) require.NoError(t, err)
return &state.Contract{ return &state.Contract{
ContractBase: state.ContractBase{
Hash: barH, Hash: barH,
NEF: *barNef, NEF: *barNef,
Manifest: *mBar, Manifest: *mBar,
},
}, nil }, nil
} }
return nil, errors.New("not found") 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 var id int32
nativeContract := bc.contracts.ByHash(sc) nativeContract := bc.contracts.ByHash(sc)
if nativeContract != nil { if nativeContract != nil {
id = nativeContract.Metadata().ContractID id = nativeContract.Metadata().ID
} else { } else {
assetContract, err := bc.contracts.Management.GetContract(cache, sc) assetContract, err := bc.contracts.Management.GetContract(cache, sc)
if err != nil { if err != nil {
@ -1018,7 +1018,7 @@ func (bc *Blockchain) GetUtilityTokenBalance(acc util.Uint160) *big.Int {
if err != nil { if err != nil {
return big.NewInt(0) return big.NewInt(0)
} }
balance := bs.Trackers[bc.contracts.GAS.ContractID].Balance balance := bs.Trackers[bc.contracts.GAS.ID].Balance
return &balance return &balance
} }
@ -1029,7 +1029,7 @@ func (bc *Blockchain) GetGoverningTokenBalance(acc util.Uint160) (*big.Int, uint
if err != nil { if err != nil {
return big.NewInt(0), 0 return big.NewInt(0), 0
} }
neo := bs.Trackers[bc.contracts.NEO.ContractID] neo := bs.Trackers[bc.contracts.NEO.ID]
return &neo.Balance, neo.LastUpdatedBlock 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") 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. // GetConfig returns the config stored in the blockchain.
func (bc *Blockchain) GetConfig() config.ProtocolConfiguration { func (bc *Blockchain) GetConfig() config.ProtocolConfiguration {
return bc.config return bc.config

View file

@ -45,6 +45,7 @@ type Blockchainer interface {
GetAppExecResults(util.Uint256, trigger.Type) ([]state.AppExecResult, error) GetAppExecResults(util.Uint256, trigger.Type) ([]state.AppExecResult, error)
GetNotaryDepositExpiration(acc util.Uint160) uint32 GetNotaryDepositExpiration(acc util.Uint160) uint32
GetNativeContractScriptHash(string) (util.Uint160, error) GetNativeContractScriptHash(string) (util.Uint160, error)
GetNatives() []state.NativeContract
GetNextBlockValidators() ([]*keys.PublicKey, error) GetNextBlockValidators() ([]*keys.PublicKey, error)
GetNEP17Balances(util.Uint160) *state.NEP17Balances GetNEP17Balances(util.Uint160) *state.NEP17Balances
GetNotaryContractScriptHash() util.Uint160 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) { 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()) require.Equal(t, int64(expected), balance.Balance.Int64())
} }

View file

@ -99,11 +99,8 @@ type Contract interface {
// ContractMD represents native contract instance. // ContractMD represents native contract instance.
type ContractMD struct { type ContractMD struct {
Manifest manifest.Manifest state.NativeContract
Name string Name string
ContractID int32
NEF nef.File
Hash util.Uint160
Methods map[MethodAndArgCount]MethodAndPrice Methods map[MethodAndArgCount]MethodAndPrice
} }
@ -117,10 +114,11 @@ type MethodAndArgCount struct {
func NewContractMD(name string, id int32) *ContractMD { func NewContractMD(name string, id int32) *ContractMD {
c := &ContractMD{ c := &ContractMD{
Name: name, Name: name,
ContractID: id,
Methods: make(map[MethodAndArgCount]MethodAndPrice), Methods: make(map[MethodAndArgCount]MethodAndPrice),
} }
c.ID = id
// NEF is now stored in contract state and affects state dump. // NEF is now stored in contract state and affects state dump.
// Therefore values are taken from C# node. // Therefore values are taken from C# node.
c.NEF.Header.Compiler = "neo-core-v3.0" 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) ne, err := nef.NewFile(script)
require.NoError(t, err) require.NoError(t, err)
contractState := &state.Contract{ contractState := &state.Contract{
ContractBase: state.ContractBase{
NEF: *ne, NEF: *ne,
Hash: hash.Hash160(script), Hash: hash.Hash160(script),
Manifest: *m, Manifest: *m,
ID: 123, ID: 123,
},
} }
chain := newTestChain(t) chain := newTestChain(t)

View file

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

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 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 { if err != nil {
return nil, 0, err return nil, 0, err
} }
@ -309,14 +309,14 @@ func (s *Designate) DesignateAsRole(ic *interop.Context, r Role, pubs keys.Publi
key[0] = byte(r) key[0] = byte(r)
binary.BigEndian.PutUint32(key[1:], ic.Block.Index+1) 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 { if si != nil {
return ErrAlreadyDesignated return ErrAlreadyDesignated
} }
sort.Sort(pubs) sort.Sort(pubs)
s.rolesChangedFlag.Store(true) s.rolesChangedFlag.Store(true)
si = &state.StorageItem{Value: NodeList(pubs).Bytes()} 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) { 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()) id := int32(ic.VM.Estack().Pop().BigInt().Int64())
var c interop.Contract var c interop.Contract
for _, ctr := range ic.Natives { for _, ctr := range ic.Natives {
if ctr.Metadata().ContractID == id { if ctr.Metadata().ID == id {
c = ctr c = ctr
break 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) { func (m *Management) getContractFromDAO(d dao.DAO, hash util.Uint160) (*state.Contract, error) {
contract := new(state.Contract) contract := new(state.Contract)
key := makeContractKey(hash) key := makeContractKey(hash)
err := getSerializableFromDAO(m.ContractID, d, key, contract) err := getSerializableFromDAO(m.ID, d, key, contract)
if err != nil { if err != nil {
return nil, err 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) { 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) h := state.CreateContractHash(sender, neff.Checksum, manif.Name)
key := makeContractKey(h) key := makeContractKey(h)
si := d.GetStorageItem(m.ContractID, key) si := d.GetStorageItem(m.ID, key)
if si != nil { if si != nil {
return nil, errors.New("contract already exists") 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 return nil, err
} }
newcontract := &state.Contract{ newcontract := &state.Contract{
ContractBase: state.ContractBase{
ID: id, ID: id,
Hash: h, Hash: h,
NEF: *neff, NEF: *neff,
Manifest: *manif, Manifest: *manif,
},
} }
err = m.PutContractState(d, newcontract) err = m.PutContractState(d, newcontract)
if err != nil { if err != nil {
@ -371,7 +373,7 @@ func (m *Management) Destroy(d dao.DAO, hash util.Uint160) error {
return err return err
} }
key := makeContractKey(hash) key := makeContractKey(hash)
err = d.DeleteStorageItem(m.ContractID, key) err = d.DeleteStorageItem(m.ID, key)
if err != nil { if err != nil {
return err return err
} }
@ -399,7 +401,7 @@ func (m *Management) getMinimumDeploymentFee(ic *interop.Context, args []stackit
// GetMinimumDeploymentFee returns the minimum required fee for contract deploy. // GetMinimumDeploymentFee returns the minimum required fee for contract deploy.
func (m *Management) GetMinimumDeploymentFee(dao dao.DAO) int64 { 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 { 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) { if !m.NEO.checkCommittee(ic) {
panic("invalid committee signature") 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 { if err != nil {
panic(err) panic(err)
} }
@ -451,10 +453,7 @@ func (m *Management) OnPersist(ic *interop.Context) error {
md := native.Metadata() md := native.Metadata()
cs := &state.Contract{ cs := &state.Contract{
ID: md.ContractID, ContractBase: md.ContractBase,
Hash: md.Hash,
NEF: md.NEF,
Manifest: md.Manifest,
} }
err := m.PutContractState(ic.DAO, cs) err := m.PutContractState(ic.DAO, cs)
if err != nil { if err != nil {
@ -479,7 +478,7 @@ func (m *Management) InitializeCache(d dao.DAO) error {
defer m.mtx.Unlock() defer m.mtx.Unlock()
var initErr error 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 r = io.NewBinReaderFromBuf(v)
var si state.StorageItem var si state.StorageItem
si.DecodeBinary(r) si.DecodeBinary(r)
@ -521,16 +520,16 @@ func (m *Management) PostPersist(ic *interop.Context) error {
// Initialize implements Contract interface. // Initialize implements Contract interface.
func (m *Management) Initialize(ic *interop.Context) error { 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 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. // PutContractState saves given contract state into given DAO.
func (m *Management) PutContractState(d dao.DAO, cs *state.Contract) error { func (m *Management) PutContractState(d dao.DAO, cs *state.Contract) error {
key := makeContractKey(cs.Hash) 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 return err
} }
m.markUpdated(cs.Hash) 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) { func (m *Management) getNextContractID(d dao.DAO) (int32, error) {
si := d.GetStorageItem(m.ContractID, keyNextAvailableID) si := d.GetStorageItem(m.ID, keyNextAvailableID)
if si == nil { if si == nil {
return 0, errors.New("nextAvailableID is not initialized") 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()) ret := int32(id.Int64())
id.Add(id, intOne) id.Add(id, intOne)
si.Value = bigint.ToPreallocatedBytes(id, si.Value) 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) { 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) { t.Run("invalid contract state", func(t *testing.T) {
d := dao.NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet, false) d := dao.NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet, false)
mgmt := newManagement() 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)) 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 { if err := n.nonfungible.Initialize(ic); err != nil {
return err 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 return err
} }
roots := stringList{} 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. // OnPersist implements interop.Contract interface.
func (n *NameService) OnPersist(ic *interop.Context) error { func (n *NameService) OnPersist(ic *interop.Context) error {
now := uint32(ic.Block.Timestamp/1000 + 1) now := uint32(ic.Block.Timestamp/1000 + 1)
keys := []string{} 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 { if binary.BigEndian.Uint32(k) >= now {
return return
} }
@ -200,20 +200,20 @@ func (n *NameService) OnPersist(ic *interop.Context) error {
for i := range keys { for i := range keys {
key[0] = prefixExpiration key[0] = prefixExpiration
key = append(key[:1], []byte(keys[i])...) 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 return err
} }
keysToRemove = keysToRemove[:0] keysToRemove = keysToRemove[:0]
key[0] = prefixRecord key[0] = prefixRecord
key = append(key[:1], keys[i][4:]...) 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) keysToRemove = append(keysToRemove, k)
}) })
for i := range keysToRemove { for i := range keysToRemove {
keyRecord = append(keyRecord[:0], key...) keyRecord = append(keyRecord[:0], key...)
keyRecord = append(keyRecord, keysToRemove[i]...) keyRecord = append(keyRecord, keysToRemove[i]...)
err := ic.DAO.DeleteStorageItem(n.ContractID, keyRecord) err := ic.DAO.DeleteStorageItem(n.ID, keyRecord)
if err != nil { if err != nil {
return err return err
} }
@ -242,7 +242,7 @@ func (n *NameService) addRoot(ic *interop.Context, args []stackitem.Item) stacki
panic("name already exists") 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 { if err != nil {
panic(err) panic(err)
} }
@ -259,7 +259,7 @@ func (n *NameService) setPrice(ic *interop.Context, args []stackitem.Item) stack
n.checkCommittee(ic) n.checkCommittee(ic)
si := &state.StorageItem{Value: bigint.ToBytes(price)} 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 { if err != nil {
panic(err) 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 { 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) 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 { func (n *NameService) isAvailable(ic *interop.Context, args []stackitem.Item) stackitem.Item {
_, names, key := n.parseName(args[0]) _, 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) 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) { func (n *NameService) getRootsInternal(d dao.DAO) (stringList, bool) {
var sl stringList var sl stringList
err := getSerializableFromDAO(n.ContractID, d, []byte{prefixRoots}, &sl) err := getSerializableFromDAO(n.ID, d, []byte{prefixRoots}, &sl)
if err != nil { if err != nil {
// Roots are being stored in `Initialize()` and thus must always be present. // Roots are being stored in `Initialize()` and thus must always be present.
panic(err) panic(err)
@ -315,7 +315,7 @@ func (n *NameService) register(ic *interop.Context, args []stackitem.Item) stack
panic("owner is not witnessed") 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) 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), Expiration: uint32(ic.Block.Timestamp/1000 + secondsInYear),
} }
n.mint(ic, token) n.mint(ic, token)
err := ic.DAO.PutStorageItem(n.ContractID, err := ic.DAO.PutStorageItem(n.ID,
makeExpirationKey(token.Expiration, token.ID()), makeExpirationKey(token.Expiration, token.ID()),
&state.StorageItem{Value: []byte{0}}) &state.StorageItem{Value: []byte{0}})
if err != nil { if err != nil {
@ -349,25 +349,25 @@ func (n *NameService) renew(ic *interop.Context, args []stackitem.Item) stackite
panic("insufficient gas") panic("insufficient gas")
} }
token := new(nameState) token := new(nameState)
err := getSerializableFromDAO(n.ContractID, ic.DAO, key, token) err := getSerializableFromDAO(n.ID, ic.DAO, key, token)
if err != nil { if err != nil {
panic(err) panic(err)
} }
keyExpiration := makeExpirationKey(token.Expiration, token.ID()) 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) panic(err)
} }
token.Expiration += secondsInYear token.Expiration += secondsInYear
err = putSerializableToDAO(n.ContractID, ic.DAO, key, token) err = putSerializableToDAO(n.ID, ic.DAO, key, token)
if err != nil { if err != nil {
panic(err) panic(err)
} }
binary.BigEndian.PutUint32(key[1:], token.Expiration) binary.BigEndian.PutUint32(key[1:], token.Expiration)
si := &state.StorageItem{Value: []byte{0}} 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 { if err != nil {
panic(err) panic(err)
} }
@ -388,7 +388,7 @@ func (n *NameService) setAdmin(ic *interop.Context, args []stackitem.Item) stack
} }
token := new(nameState) token := new(nameState)
err := getSerializableFromDAO(n.ContractID, ic.DAO, key, token) err := getSerializableFromDAO(n.ID, ic.DAO, key, token)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -397,7 +397,7 @@ func (n *NameService) setAdmin(ic *interop.Context, args []stackitem.Item) stack
} }
token.HasAdmin = !isNull token.HasAdmin = !isNull
token.Admin = admin token.Admin = admin
err = putSerializableToDAO(n.ContractID, ic.DAO, key, token) err = putSerializableToDAO(n.ID, ic.DAO, key, token)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -441,7 +441,7 @@ func (n *NameService) setRecord(ic *interop.Context, args []stackitem.Item) stac
} }
key := makeRecordKey(domain, name, rt) key := makeRecordKey(domain, name, rt)
si := &state.StorageItem{Value: []byte(data)} 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) panic(err)
} }
return stackitem.Null{} return stackitem.Null{}
@ -473,7 +473,7 @@ func (n *NameService) getRecord(ic *interop.Context, args []stackitem.Item) stac
domain := toDomain(name) domain := toDomain(name)
rt := toRecordType(args[1]) rt := toRecordType(args[1])
key := makeRecordKey(domain, name, rt) key := makeRecordKey(domain, name, rt)
si := ic.DAO.GetStorageItem(n.ContractID, key) si := ic.DAO.GetStorageItem(n.ID, key)
if si == nil { if si == nil {
return stackitem.Null{} return stackitem.Null{}
} }
@ -486,7 +486,7 @@ func (n *NameService) deleteRecord(ic *interop.Context, args []stackitem.Item) s
domain := toDomain(name) domain := toDomain(name)
key := n.getTokenKey([]byte(domain)) key := n.getTokenKey([]byte(domain))
token := new(nameState) token := new(nameState)
err := getSerializableFromDAO(n.ContractID, ic.DAO, key, token) err := getSerializableFromDAO(n.ID, ic.DAO, key, token)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -496,7 +496,7 @@ func (n *NameService) deleteRecord(ic *interop.Context, args []stackitem.Item) s
} }
key = makeRecordKey(domain, name, rt) 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) panic(err)
} }
return stackitem.Null{} return stackitem.Null{}
@ -532,7 +532,7 @@ func (n *NameService) getRecordsInternal(d dao.DAO, name string) map[RecordType]
key := makeRecordKey(domain, name, 0) key := makeRecordKey(domain, name, 0)
key = key[:len(key)-1] key = key[:len(key)-1]
res := make(map[RecordType]string) 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]) rt := RecordType(k[len(k)-1])
var si state.StorageItem var si state.StorageItem
r := io.NewBinReaderFromBuf(v) r := io.NewBinReaderFromBuf(v)

View file

@ -170,7 +170,7 @@ func (n *NEO) Initialize(ic *interop.Context) error {
return err 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 { if err != nil {
return err return err
} }
@ -190,7 +190,7 @@ func (n *NEO) Initialize(ic *interop.Context) error {
gr := &gasRecord{{Index: index, GASPerBlock: *value}} gr := &gasRecord{{Index: index, GASPerBlock: *value}}
n.gasPerBlock.Store(*gr) n.gasPerBlock.Store(*gr)
n.gasPerBlockChanged.Store(false) 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 { if err != nil {
return err return err
} }
@ -203,7 +203,7 @@ func (n *NEO) Initialize(ic *interop.Context) error {
// called only when deploying native contracts. // called only when deploying native contracts.
func (n *NEO) InitializeCache(bc blockchainer.Blockchainer, d dao.DAO) error { func (n *NEO) InitializeCache(bc blockchainer.Blockchainer, d dao.DAO) error {
var committee = keysWithVotes{} var committee = keysWithVotes{}
si := d.GetStorageItem(n.ContractID, prefixCommittee) si := d.GetStorageItem(n.ID, prefixCommittee)
if err := committee.DecodeBytes(si.Value); err != nil { if err := committee.DecodeBytes(si.Value); err != nil {
return err 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 // We need to put in storage anyway, as it affects dumps
committee := n.committee.Load().(keysWithVotes) committee := n.committee.Load().(keysWithVotes)
si := &state.StorageItem{Value: committee.Bytes()} 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) _, cvs, err := n.computeCommitteeMembers(ic.Chain, ic.DAO)
@ -255,7 +255,7 @@ func (n *NEO) updateCommittee(ic *interop.Context) error {
} }
n.votesChanged.Store(false) n.votesChanged.Store(false)
si := &state.StorageItem{Value: cvs.Bytes()} 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. // 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) binary.BigEndian.PutUint32(key[34:], ic.Block.Index+1)
si.Value = bigint.ToBytes(tmp) 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 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 max = make([]uint32, len(index))
var reward = make([]big.Int, len(index)) var reward = make([]big.Int, len(index))
var si state.StorageItem 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 { if len(k) == 4 {
num := binary.BigEndian.Uint32(k) num := binary.BigEndian.Uint32(k)
for i, ind := range index { 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) { 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 { if err != nil {
return gasRecord{}, fmt.Errorf("failed to get gas records from storage: %w", err) 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 { if c.Registered || c.Votes.Sign() != 0 {
return false, nil 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 return true, err
} }
var toRemove []string 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)) toRemove = append(toRemove, string(k))
}) })
for i := range toRemove { 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 return true, err
} }
} }
@ -527,7 +527,7 @@ func makeVoterKey(pub []byte, prealloc ...[]byte) []byte {
// and having voted for active committee member. // and having voted for active committee member.
func (n *NEO) CalculateBonus(d dao.DAO, acc util.Uint160, end uint32) (*big.Int, error) { func (n *NEO) CalculateBonus(d dao.DAO, acc util.Uint160, end uint32) (*big.Int, error) {
key := makeAccountKey(acc) key := makeAccountKey(acc)
si := d.GetStorageItem(n.ContractID, key) si := d.GetStorageItem(n.ID, key)
if si == nil { if si == nil {
return nil, storage.ErrKeyNotFound 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. // RegisterCandidateInternal registers pub as a new candidate.
func (n *NEO) RegisterCandidateInternal(ic *interop.Context, pub *keys.PublicKey) error { func (n *NEO) RegisterCandidateInternal(ic *interop.Context, pub *keys.PublicKey) error {
key := makeValidatorKey(pub) key := makeValidatorKey(pub)
si := ic.DAO.GetStorageItem(n.ContractID, key) si := ic.DAO.GetStorageItem(n.ID, key)
if si == nil { if si == nil {
c := &candidate{Registered: true} c := &candidate{Registered: true}
si = &state.StorageItem{Value: c.Bytes()} si = &state.StorageItem{Value: c.Bytes()}
@ -617,7 +617,7 @@ func (n *NEO) RegisterCandidateInternal(ic *interop.Context, pub *keys.PublicKey
c.Registered = true c.Registered = true
si.Value = c.Bytes() 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 { 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. // UnregisterCandidateInternal unregisters pub as a candidate.
func (n *NEO) UnregisterCandidateInternal(ic *interop.Context, pub *keys.PublicKey) error { func (n *NEO) UnregisterCandidateInternal(ic *interop.Context, pub *keys.PublicKey) error {
key := makeValidatorKey(pub) key := makeValidatorKey(pub)
si := ic.DAO.GetStorageItem(n.ContractID, key) si := ic.DAO.GetStorageItem(n.ID, key)
if si == nil { if si == nil {
return nil return nil
} }
@ -647,7 +647,7 @@ func (n *NEO) UnregisterCandidateInternal(ic *interop.Context, pub *keys.PublicK
return err return err
} }
si.Value = c.Bytes() 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 { 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") return errors.New("invalid signature")
} }
key := makeAccountKey(h) key := makeAccountKey(h)
si := ic.DAO.GetStorageItem(n.ContractID, key) si := ic.DAO.GetStorageItem(n.ID, key)
if si == nil { if si == nil {
return errors.New("invalid account") return errors.New("invalid account")
} }
@ -697,7 +697,7 @@ func (n *NEO) VoteInternal(ic *interop.Context, h util.Uint160, pub *keys.Public
return err return err
} }
si.Value = acc.Bytes() 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). // 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) n.votesChanged.Store(true)
if acc.VoteTo != nil { if acc.VoteTo != nil {
key := makeValidatorKey(acc.VoteTo) key := makeValidatorKey(acc.VoteTo)
si := d.GetStorageItem(n.ContractID, key) si := d.GetStorageItem(n.ID, key)
if si == nil { if si == nil {
return errors.New("invalid validator") 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)) n.validators.Store(keys.PublicKeys(nil))
si.Value = cd.Bytes() si.Value = cd.Bytes()
return d.PutStorageItem(n.ContractID, key, si) return d.PutStorageItem(n.ID, key, si)
} }
return nil return nil
} }
func (n *NEO) getCandidates(d dao.DAO, sortByKey bool) ([]keyWithVotes, error) { 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 { if err != nil {
return nil, err 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 { func (n *NEO) modifyVoterTurnout(d dao.DAO, amount *big.Int) error {
key := []byte{prefixVotersCount} key := []byte{prefixVotersCount}
si := d.GetStorageItem(n.ContractID, key) si := d.GetStorageItem(n.ID, key)
if si == nil { if si == nil {
return errors.New("voters count not found") return errors.New("voters count not found")
} }
votersCount := bigint.FromBytes(si.Value) votersCount := bigint.FromBytes(si.Value)
votersCount.Add(votersCount, amount) votersCount.Add(votersCount, amount)
si.Value = bigint.ToBytes(votersCount) 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. // 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. // computeCommitteeMembers returns public keys of nodes in committee.
func (n *NEO) computeCommitteeMembers(bc blockchainer.Blockchainer, d dao.DAO) (keys.PublicKeys, keysWithVotes, error) { func (n *NEO) computeCommitteeMembers(bc blockchainer.Blockchainer, d dao.DAO) (keys.PublicKeys, keysWithVotes, error) {
key := []byte{prefixVotersCount} key := []byte{prefixVotersCount}
si := d.GetStorageItem(n.ContractID, key) si := d.GetStorageItem(n.ID, key)
if si == nil { if si == nil {
return nil, nil, errors.New("voters count not found") 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), Value: bigint.ToBytes(value),
IsConst: false, 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 { func (c *nep17TokenNative) getTotalSupply(d dao.DAO) *big.Int {
si := d.GetStorageItem(c.ContractID, totalSupplyKey) si := d.GetStorageItem(c.ID, totalSupplyKey)
if si == nil { if si == nil {
return big.NewInt(0) 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 { func (c *nep17TokenNative) saveTotalSupply(d dao.DAO, supply *big.Int) error {
si := &state.StorageItem{Value: bigint.ToBytes(supply)} 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 { 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 { func (c *nep17TokenNative) updateAccBalance(ic *interop.Context, acc util.Uint160, amount *big.Int) error {
key := makeAccountKey(acc) key := makeAccountKey(acc)
si := ic.DAO.GetStorageItem(c.ContractID, key) si := ic.DAO.GetStorageItem(c.ID, key)
if si == nil { if si == nil {
if amount.Sign() <= 0 { if amount.Sign() <= 0 {
return errors.New("insufficient funds") return errors.New("insufficient funds")
@ -176,9 +176,9 @@ func (c *nep17TokenNative) updateAccBalance(ic *interop.Context, acc util.Uint16
return err return err
} }
if si.Value == nil { if si.Value == nil {
err = ic.DAO.DeleteStorageItem(c.ContractID, key) err = ic.DAO.DeleteStorageItem(c.ID, key)
} else { } else {
err = ic.DAO.PutStorageItem(c.ContractID, key, si) err = ic.DAO.PutStorageItem(c.ID, key, si)
} }
return err return err
} }
@ -225,7 +225,7 @@ func (c *nep17TokenNative) balanceOf(ic *interop.Context, args []stackitem.Item)
if err != nil { if err != nil {
panic(err) panic(err)
} }
balance := bs.Trackers[c.ContractID].Balance balance := bs.Trackers[c.ID].Balance
return stackitem.NewBigInteger(&balance) return stackitem.NewBigInteger(&balance)
} }
@ -251,14 +251,14 @@ func (c *nep17TokenNative) addTokens(ic *interop.Context, h util.Uint160, amount
} }
key := makeAccountKey(h) key := makeAccountKey(h)
si := ic.DAO.GetStorageItem(c.ContractID, key) si := ic.DAO.GetStorageItem(c.ID, key)
if si == nil { if si == nil {
si = new(state.StorageItem) si = new(state.StorageItem)
} }
if err := c.incBalance(ic, h, si, amount); err != nil { if err := c.incBalance(ic, h, si, amount); err != nil {
panic(err) panic(err)
} }
if err := ic.DAO.PutStorageItem(c.ContractID, key, si); err != nil { if err := ic.DAO.PutStorageItem(c.ID, key, si); err != nil {
panic(err) panic(err)
} }

View file

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

View file

@ -108,7 +108,7 @@ func (n *Notary) Metadata() *interop.ContractMD {
// Initialize initializes Notary native contract and implements Contract interface. // Initialize initializes Notary native contract and implements Contract interface.
func (n *Notary) Initialize(ic *interop.Context) error { 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 { if err != nil {
return err return err
} }
@ -171,7 +171,7 @@ func (n *Notary) PostPersist(ic *interop.Context) error {
return nil return nil
} }
n.maxNotValidBeforeDelta = uint32(getIntWithKey(n.ContractID, ic.DAO, maxNotValidBeforeDeltaKey)) n.maxNotValidBeforeDelta = uint32(getIntWithKey(n.ID, ic.DAO, maxNotValidBeforeDeltaKey))
n.isValid = true n.isValid = true
return nil return nil
} }
@ -384,7 +384,7 @@ func (n *Notary) GetMaxNotValidBeforeDelta(dao dao.DAO) uint32 {
if n.isValid { if n.isValid {
return n.maxNotValidBeforeDelta 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. // 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() n.lock.Lock()
defer n.lock.Unlock() 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 { if err != nil {
panic(fmt.Errorf("failed to put value into the storage: %w", err)) 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 { func (n *Notary) GetDepositFor(dao dao.DAO, acc util.Uint160) *state.Deposit {
key := append([]byte{prefixDeposit}, acc.BytesBE()...) key := append([]byte{prefixDeposit}, acc.BytesBE()...)
deposit := new(state.Deposit) deposit := new(state.Deposit)
err := getSerializableFromDAO(n.ContractID, dao, key, deposit) err := getSerializableFromDAO(n.ID, dao, key, deposit)
if err == nil { if err == nil {
return deposit 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. // 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 { func (n *Notary) putDepositFor(dao dao.DAO, deposit *state.Deposit, acc util.Uint160) error {
key := append([]byte{prefixDeposit}, acc.BytesBE()...) 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. // removeDepositFor removes deposit from the storage.
func (n *Notary) removeDepositFor(dao dao.DAO, acc util.Uint160) error { func (n *Notary) removeDepositFor(dao dao.DAO, acc util.Uint160) error {
key := append([]byte{prefixDeposit}, acc.BytesBE()...) 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. // 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 { if err := o.getSerializableFromDAO(ic.DAO, reqKey, req); err != nil {
continue continue
} }
if err := ic.DAO.DeleteStorageItem(o.ContractID, reqKey); err != nil { if err := ic.DAO.DeleteStorageItem(o.ID, reqKey); err != nil {
return err return err
} }
if orc != nil { if orc != nil {
@ -163,10 +163,10 @@ func (o *Oracle) PostPersist(ic *interop.Context) error {
var err error var err error
if len(*idList) == 0 { if len(*idList) == 0 {
err = ic.DAO.DeleteStorageItem(o.ContractID, idKey) err = ic.DAO.DeleteStorageItem(o.ID, idKey)
} else { } else {
si := &state.StorageItem{Value: idList.Bytes()} 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 { if err != nil {
return err return err
@ -202,7 +202,7 @@ func (o *Oracle) Metadata() *interop.ContractMD {
// Initialize initializes Oracle contract. // Initialize initializes Oracle contract.
func (o *Oracle) Initialize(ic *interop.Context) error { 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 { 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() callingHash := ic.VM.GetCallingScriptHash()
o.GAS.mint(ic, o.Hash, gas, false) 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) itemID := bigint.FromBytes(si.Value)
id := itemID.Uint64() id := itemID.Uint64()
itemID.Add(itemID, intOne) itemID.Add(itemID, intOne)
si.Value = bigint.ToPreallocatedBytes(itemID, si.Value) 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 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 { func (o *Oracle) PutRequestInternal(id uint64, req *state.OracleRequest, d dao.DAO) error {
reqItem := &state.StorageItem{Value: req.Bytes()} reqItem := &state.StorageItem{Value: req.Bytes()}
reqKey := makeRequestKey(id) 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 return err
} }
o.newRequests[id] = req o.newRequests[id] = req
@ -374,7 +374,7 @@ func (o *Oracle) PutRequestInternal(id uint64, req *state.OracleRequest, d dao.D
} }
*lst = append(*lst, id) *lst = append(*lst, id)
si := &state.StorageItem{Value: lst.Bytes()} 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. // 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. // getRequests returns all requests which have not been finished yet.
func (o *Oracle) getRequests(d dao.DAO) (map[uint64]*state.OracleRequest, error) { 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 { if err != nil {
return nil, err 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 { 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 // 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) o.newRequests = make(map[uint64]*state.OracleRequest)
for id := range reqs { for id := range reqs {
key := makeRequestKey(id) 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) delete(reqs, id)
} }
} }

View file

@ -166,22 +166,22 @@ func (p *Policy) Metadata() *interop.ContractMD {
// Initialize initializes Policy native contract and implements Contract interface. // Initialize initializes Policy native contract and implements Contract interface.
func (p *Policy) Initialize(ic *interop.Context) error { 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 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 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 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 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 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 return err
} }
@ -211,16 +211,16 @@ func (p *Policy) PostPersist(ic *interop.Context) error {
return nil return nil
} }
p.maxTransactionsPerBlock = uint32(getIntWithKey(p.ContractID, ic.DAO, maxTransactionsPerBlockKey)) p.maxTransactionsPerBlock = uint32(getIntWithKey(p.ID, ic.DAO, maxTransactionsPerBlockKey))
p.maxBlockSize = uint32(getIntWithKey(p.ContractID, ic.DAO, maxBlockSizeKey)) p.maxBlockSize = uint32(getIntWithKey(p.ID, ic.DAO, maxBlockSizeKey))
p.execFeeFactor = uint32(getIntWithKey(p.ContractID, ic.DAO, execFeeFactorKey)) p.execFeeFactor = uint32(getIntWithKey(p.ID, ic.DAO, execFeeFactorKey))
p.feePerByte = getIntWithKey(p.ContractID, ic.DAO, feePerByteKey) p.feePerByte = getIntWithKey(p.ID, ic.DAO, feePerByteKey)
p.maxBlockSystemFee = getIntWithKey(p.ContractID, ic.DAO, maxBlockSystemFeeKey) p.maxBlockSystemFee = getIntWithKey(p.ID, ic.DAO, maxBlockSystemFeeKey)
p.maxVerificationGas = defaultMaxVerificationGas 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) 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 { if err != nil {
return fmt.Errorf("failed to get blocked accounts from storage: %w", err) 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 { if p.isValid {
return p.maxTransactionsPerBlock 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. // 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 { if p.isValid {
return p.maxBlockSize 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 // 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 { if p.isValid {
return p.feePerByte 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. // 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 { if p.isValid {
return p.maxBlockSystemFee 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 { 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 { if p.isValid {
return int64(p.execFeeFactor) 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 { 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() p.lock.Lock()
defer p.lock.Unlock() 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 { if err != nil {
panic(err) panic(err)
} }
@ -364,7 +364,7 @@ func (p *Policy) IsBlockedInternal(dao dao.DAO, hash util.Uint160) bool {
return false return false
} }
key := append([]byte{blockedAccountPrefix}, hash.BytesBE()...) 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 { 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 { if p.isValid {
return int64(p.storagePrice) 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 { 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() p.lock.Lock()
defer p.lock.Unlock() 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 { if err != nil {
panic(err) panic(err)
} }
@ -411,7 +411,7 @@ func (p *Policy) setMaxTransactionsPerBlock(ic *interop.Context, args []stackite
} }
p.lock.Lock() p.lock.Lock()
defer p.lock.Unlock() 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 { if err != nil {
panic(err) panic(err)
} }
@ -430,7 +430,7 @@ func (p *Policy) setMaxBlockSize(ic *interop.Context, args []stackitem.Item) sta
} }
p.lock.Lock() p.lock.Lock()
defer p.lock.Unlock() 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 { if err != nil {
panic(err) panic(err)
} }
@ -449,7 +449,7 @@ func (p *Policy) setFeePerByte(ic *interop.Context, args []stackitem.Item) stack
} }
p.lock.Lock() p.lock.Lock()
defer p.lock.Unlock() defer p.lock.Unlock()
err := setIntWithKey(p.ContractID, ic.DAO, feePerByteKey, value) err := setIntWithKey(p.ID, ic.DAO, feePerByteKey, value)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -468,7 +468,7 @@ func (p *Policy) setMaxBlockSystemFee(ic *interop.Context, args []stackitem.Item
} }
p.lock.Lock() p.lock.Lock()
defer p.lock.Unlock() defer p.lock.Unlock()
err := setIntWithKey(p.ContractID, ic.DAO, maxBlockSystemFeeKey, value) err := setIntWithKey(p.ID, ic.DAO, maxBlockSystemFeeKey, value)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -489,7 +489,7 @@ func (p *Policy) blockAccount(ic *interop.Context, args []stackitem.Item) stacki
key := append([]byte{blockedAccountPrefix}, hash.BytesBE()...) key := append([]byte{blockedAccountPrefix}, hash.BytesBE()...)
p.lock.Lock() p.lock.Lock()
defer p.lock.Unlock() defer p.lock.Unlock()
err := ic.DAO.PutStorageItem(p.ContractID, key, &state.StorageItem{ err := ic.DAO.PutStorageItem(p.ID, key, &state.StorageItem{
Value: []byte{}, Value: []byte{},
}) })
if err != nil { if err != nil {
@ -512,7 +512,7 @@ func (p *Policy) unblockAccount(ic *interop.Context, args []stackitem.Item) stac
key := append([]byte{blockedAccountPrefix}, hash.BytesBE()...) key := append([]byte{blockedAccountPrefix}, hash.BytesBE()...)
p.lock.Lock() p.lock.Lock()
defer p.lock.Unlock() defer p.lock.Unlock()
err := ic.DAO.DeleteStorageItem(p.ContractID, key) err := ic.DAO.DeleteStorageItem(p.ID, key)
if err != nil { if err != nil {
panic(err) panic(err)
} }

View file

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

View file

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

View file

@ -18,13 +18,24 @@ import (
// Contract holds information about a smart contract in the NEO blockchain. // Contract holds information about a smart contract in the NEO blockchain.
type Contract struct { type Contract struct {
ID int32 `json:"id"` ContractBase
UpdateCounter uint16 `json:"updatecounter"` 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"` Hash util.Uint160 `json:"hash"`
NEF nef.File `json:"nef"` NEF nef.File `json:"nef"`
Manifest manifest.Manifest `json:"manifest"` Manifest manifest.Manifest `json:"manifest"`
} }
// NativeContract holds information about native contract.
type NativeContract struct {
ContractBase
ActiveBlockIndex uint32 `json:"activeblockindex"`
}
// DecodeBinary implements Serializable interface. // DecodeBinary implements Serializable interface.
func (c *Contract) DecodeBinary(r *io.BinReader) { func (c *Contract) DecodeBinary(r *io.BinReader) {
si := stackitem.DecodeBinaryStackItem(r) si := stackitem.DecodeBinaryStackItem(r)

View file

@ -34,8 +34,9 @@ func TestEncodeDecodeContractState(t *testing.T) {
ReturnType: smartcontract.BoolType, ReturnType: smartcontract.BoolType,
}} }}
contract := &Contract{ contract := &Contract{
ID: 123,
UpdateCounter: 42, UpdateCounter: 42,
ContractBase: ContractBase{
ID: 123,
Hash: h, Hash: h,
NEF: nef.File{ NEF: nef.File{
Header: nef.Header{ Header: nef.Header{
@ -47,6 +48,7 @@ func TestEncodeDecodeContractState(t *testing.T) {
Checksum: 0, Checksum: 0,
}, },
Manifest: *m, Manifest: *m,
},
} }
contract.NEF.Checksum = contract.NEF.CalculateChecksum() contract.NEF.Checksum = contract.NEF.CalculateChecksum()

View file

@ -240,6 +240,18 @@ func (c *Client) getContractState(param interface{}) (*state.Contract, error) {
return resp, nil 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. // GetNEP17Balances is a wrapper for getnep17balances RPC.
func (c *Client) GetNEP17Balances(address util.Uint160) (*result.NEP17Balances, error) { func (c *Client) GetNEP17Balances(address util.Uint160) (*result.NEP17Balances, error) {
params := request.NewRawParams(address.StringLE()) params := request.NewRawParams(address.StringLE())

View file

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

View file

@ -322,3 +322,17 @@ func TestInvokeVerify(t *testing.T) {
require.False(t, res.Stack[0].Value().(bool)) 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, "getcommittee": (*Server).getCommittee,
"getconnectioncount": (*Server).getConnectionCount, "getconnectioncount": (*Server).getConnectionCount,
"getcontractstate": (*Server).getContractState, "getcontractstate": (*Server).getContractState,
"getnativecontracts": (*Server).getNativeContracts,
"getnep17balances": (*Server).getNEP17Balances, "getnep17balances": (*Server).getNEP17Balances,
"getnep17transfers": (*Server).getNEP17Transfers, "getnep17transfers": (*Server).getNEP17Transfers,
"getpeers": (*Server).getPeers, "getpeers": (*Server).getPeers,
@ -986,6 +987,10 @@ func (s *Server) getContractState(reqParams request.Params) (interface{}, *respo
return cs, nil 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. // getBlockSysFee returns the system fees of the block, based on the specified index.
func (s *Server) getBlockSysFee(reqParams request.Params) (interface{}, *response.Error) { func (s *Server) getBlockSysFee(reqParams request.Params) (interface{}, *response.Error) {
param := reqParams.ValueWithType(0, request.NumberT) 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": { "getpeers": {
{ {
params: "[]", params: "[]",