Merge pull request #1978 from nspcc-dev/interop-getaccountstate
native/neo: add `getAccountState` method, close #1975
This commit is contained in:
commit
93a331818e
5 changed files with 63 additions and 1 deletions
|
@ -316,7 +316,7 @@ func canConvert(s string) bool {
|
||||||
s = s[len(interopPrefix):]
|
s = s[len(interopPrefix):]
|
||||||
return s != "/iterator.Iterator" && s != "/storage.Context" &&
|
return s != "/iterator.Iterator" && s != "/storage.Context" &&
|
||||||
s != "/native/ledger.Block" && s != "/native/ledger.Transaction" &&
|
s != "/native/ledger.Block" && s != "/native/ledger.Transaction" &&
|
||||||
s != "/native/management.Contract"
|
s != "/native/management.Contract" && s != "/native/neo.AccountState"
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,6 +116,7 @@ func TestNativeHelpersCompile(t *testing.T) {
|
||||||
{"vote", []string{u160, pub}},
|
{"vote", []string{u160, pub}},
|
||||||
{"unclaimedGas", []string{u160, "123"}},
|
{"unclaimedGas", []string{u160, "123"}},
|
||||||
{"unregisterCandidate", []string{pub}},
|
{"unregisterCandidate", []string{pub}},
|
||||||
|
{"getAccountState", []string{u160}},
|
||||||
}, nep17TestCases...))
|
}, nep17TestCases...))
|
||||||
runNativeTestCases(t, cs.GAS.ContractMD, "gas", append([]nativeTestCase{
|
runNativeTestCases(t, cs.GAS.ContractMD, "gas", append([]nativeTestCase{
|
||||||
{"refuel", []string{u160, "123"}},
|
{"refuel", []string{u160, "123"}},
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||||
|
@ -143,6 +144,11 @@ func newNEO() *NEO {
|
||||||
md = newMethodAndPrice(n.getCandidatesCall, 1<<22, callflag.ReadStates)
|
md = newMethodAndPrice(n.getCandidatesCall, 1<<22, callflag.ReadStates)
|
||||||
n.AddMethod(md, desc)
|
n.AddMethod(md, desc)
|
||||||
|
|
||||||
|
desc = newDescriptor("getAccountState", smartcontract.ArrayType,
|
||||||
|
manifest.NewParameter("account", smartcontract.Hash160Type))
|
||||||
|
md = newMethodAndPrice(n.getAccountState, 1<<15, callflag.ReadStates)
|
||||||
|
n.AddMethod(md, desc)
|
||||||
|
|
||||||
desc = newDescriptor("getCommittee", smartcontract.ArrayType)
|
desc = newDescriptor("getCommittee", smartcontract.ArrayType)
|
||||||
md = newMethodAndPrice(n.getCommittee, 1<<16, callflag.ReadStates)
|
md = newMethodAndPrice(n.getCommittee, 1<<16, callflag.ReadStates)
|
||||||
n.AddMethod(md, desc)
|
n.AddMethod(md, desc)
|
||||||
|
@ -863,6 +869,21 @@ func (n *NEO) getCandidatesCall(ic *interop.Context, _ []stackitem.Item) stackit
|
||||||
return stackitem.NewArray(arr)
|
return stackitem.NewArray(arr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *NEO) getAccountState(ic *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||||
|
key := makeAccountKey(toUint160(args[0]))
|
||||||
|
si := ic.DAO.GetStorageItem(n.ID, key)
|
||||||
|
if len(si) == 0 {
|
||||||
|
return stackitem.Null{}
|
||||||
|
}
|
||||||
|
|
||||||
|
r := io.NewBinReaderFromBuf(si)
|
||||||
|
item := stackitem.DecodeBinaryStackItem(r)
|
||||||
|
if r.Err != nil {
|
||||||
|
panic(r.Err) // no errors are expected but we better be sure
|
||||||
|
}
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
|
||||||
// ComputeNextBlockValidators returns an actual list of current validators.
|
// ComputeNextBlockValidators returns an actual list of current validators.
|
||||||
func (n *NEO) ComputeNextBlockValidators(bc blockchainer.Blockchainer, d dao.DAO) (keys.PublicKeys, error) {
|
func (n *NEO) ComputeNextBlockValidators(bc blockchainer.Blockchainer, d dao.DAO) (keys.PublicKeys, error) {
|
||||||
if vals := n.validators.Load().(keys.PublicKeys); vals != nil {
|
if vals := n.validators.Load().(keys.PublicKeys); vals != nil {
|
||||||
|
|
|
@ -229,6 +229,34 @@ func TestNEO_CalculateBonus(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNEO_GetAccountState(t *testing.T) {
|
||||||
|
bc := newTestChain(t)
|
||||||
|
|
||||||
|
acc, err := wallet.NewAccount()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
h := acc.Contract.ScriptHash()
|
||||||
|
t.Run("empty", func(t *testing.T) {
|
||||||
|
res, err := invokeContractMethod(bc, 1_0000000, bc.contracts.NEO.Hash, "getAccountState", h)
|
||||||
|
require.NoError(t, err)
|
||||||
|
checkResult(t, res, stackitem.Null{})
|
||||||
|
})
|
||||||
|
|
||||||
|
const amount = 123
|
||||||
|
transferTokenFromMultisigAccountCheckOK(t, bc, h, bc.GoverningTokenHash(), int64(amount))
|
||||||
|
|
||||||
|
t.Run("with funds", func(t *testing.T) {
|
||||||
|
bs := stackitem.NewStruct([]stackitem.Item{
|
||||||
|
stackitem.Make(123),
|
||||||
|
stackitem.Make(bc.BlockHeight()),
|
||||||
|
stackitem.Null{},
|
||||||
|
})
|
||||||
|
res, err := invokeContractMethod(bc, 1_0000000, bc.contracts.NEO.Hash, "getAccountState", h)
|
||||||
|
require.NoError(t, err)
|
||||||
|
checkResult(t, res, bs)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestNEO_CommitteeBountyOnPersist(t *testing.T) {
|
func TestNEO_CommitteeBountyOnPersist(t *testing.T) {
|
||||||
bc := newTestChain(t)
|
bc := newTestChain(t)
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,13 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
"github.com/nspcc-dev/neo-go/pkg/interop/contract"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// AccountState contains info about NEO holder.
|
||||||
|
type AccountState struct {
|
||||||
|
Balance int
|
||||||
|
Height int
|
||||||
|
VoteTo interop.PublicKey
|
||||||
|
}
|
||||||
|
|
||||||
// Hash represents NEO contract hash.
|
// Hash represents NEO contract hash.
|
||||||
const Hash = "\xf5\x63\xea\x40\xbc\x28\x3d\x4d\x0e\x05\xc4\x8e\xa3\x05\xb3\xf2\xa0\x73\x40\xef"
|
const Hash = "\xf5\x63\xea\x40\xbc\x28\x3d\x4d\x0e\x05\xc4\x8e\xa3\x05\xb3\xf2\xa0\x73\x40\xef"
|
||||||
|
|
||||||
|
@ -94,3 +101,8 @@ func Vote(addr interop.Hash160, pub interop.PublicKey) bool {
|
||||||
func UnclaimedGAS(addr interop.Hash160, end int) int {
|
func UnclaimedGAS(addr interop.Hash160, end int) int {
|
||||||
return contract.Call(interop.Hash160(Hash), "unclaimedGas", contract.ReadStates, addr, end).(int)
|
return contract.Call(interop.Hash160(Hash), "unclaimedGas", contract.ReadStates, addr, end).(int)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAccountState represents `getAccountState` method of NEO native contract.
|
||||||
|
func GetAccountState(addr interop.Hash160) *AccountState {
|
||||||
|
return contract.Call(interop.Hash160(Hash), "getAccountState", contract.ReadStates, addr).(*AccountState)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue