diff --git a/pkg/consensus/consensus.go b/pkg/consensus/consensus.go index 144c18897..151160622 100644 --- a/pkg/consensus/consensus.go +++ b/pkg/consensus/consensus.go @@ -479,22 +479,12 @@ func (s *service) getVerifiedTx(count int) []block.Transaction { return res } -func (s *service) getValidators(txx ...block.Transaction) []crypto.PublicKey { +func (s *service) getValidators(_ ...block.Transaction) []crypto.PublicKey { var ( pKeys []*keys.PublicKey err error ) - if len(txx) == 0 { - pKeys, err = s.Chain.GetValidators() - } else { - ntxx := make([]*transaction.Transaction, len(txx)) - for i := range ntxx { - ntxx[i] = txx[i].(*transaction.Transaction) - } - - pKeys, err = s.Chain.GetValidators(ntxx...) - } - + pKeys, err = s.Chain.GetValidators() if err != nil { s.log.Error("error while trying to get validators", zap.Error(err)) } diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 8d4df662e..37ae27923 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -630,14 +630,6 @@ func (bc *Blockchain) storeBlock(block *block.Block) error { return err } } - case *transaction.EnrollmentTX: - if err := processEnrollmentTX(cache, t); err != nil { - return err - } - case *transaction.StateTX: - if err := bc.processStateTX(cache, tx, t); err != nil { - return err - } case *transaction.InvocationTX: systemInterop := bc.newInteropContext(trigger.Application, cache, block, tx) v := SpawnVM(systemInterop) @@ -839,26 +831,6 @@ func processOutputs(tx *transaction.Transaction, dao *dao.Cached) error { return nil } -func processValidatorStateDescriptor(descriptor *transaction.StateDescriptor, dao *dao.Cached) error { - publicKey := &keys.PublicKey{} - err := publicKey.DecodeBytes(descriptor.Key) - if err != nil { - return err - } - validatorState, err := dao.GetValidatorStateOrNew(publicKey) - if err != nil { - return err - } - if descriptor.Field == "Registered" { - if len(descriptor.Value) == 1 { - validatorState.Registered = descriptor.Value[0] != 0 - return dao.PutValidatorState(validatorState) - } - return errors.New("bad descriptor value") - } - return nil -} - func (bc *Blockchain) processAccountStateDescriptor(descriptor *transaction.StateDescriptor, t *transaction.Transaction, dao *dao.Cached) error { hash, err := util.Uint160DecodeBytesBE(descriptor.Key) if err != nil { @@ -1335,7 +1307,7 @@ func (bc *Blockchain) verifyTx(t *transaction.Transaction, block *block.Block) e for _, k := range votes { var isRegistered bool for i := range validators { - if k.Equal(validators[i].PublicKey) { + if k.Equal(validators[i].Key) { isRegistered = true break } @@ -1631,128 +1603,14 @@ func (bc *Blockchain) GetStandByValidators() (keys.PublicKeys, error) { return getValidators(bc.config) } -// GetValidators returns validators. -// Golang implementation of GetValidators method in C# (https://github.com/neo-project/neo/blob/c64748ecbac3baeb8045b16af0d518398a6ced24/neo/Persistence/Snapshot.cs#L182) -func (bc *Blockchain) GetValidators(txes ...*transaction.Transaction) ([]*keys.PublicKey, error) { - cache := dao.NewCached(bc.dao) - if len(txes) > 0 { - for _, tx := range txes { - // iterate through outputs - for index, output := range tx.Outputs { - accountState, err := cache.GetAccountStateOrNew(output.ScriptHash) - if err != nil { - return nil, err - } - accountState.Balances[output.AssetID] = append(accountState.Balances[output.AssetID], state.UnspentBalance{ - Tx: tx.Hash(), - Index: uint16(index), - Value: output.Amount, - }) - if err := cache.PutAccountState(accountState); err != nil { - return nil, err - } - } - - // group inputs by the same previous hash and iterate through inputs - group := make(map[util.Uint256][]*transaction.Input) - for i := range tx.Inputs { - hash := tx.Inputs[i].PrevHash - group[hash] = append(group[hash], &tx.Inputs[i]) - } - - for hash, inputs := range group { - unspent, err := cache.GetUnspentCoinState(hash) - if err != nil { - return nil, err - } - // process inputs - for _, input := range inputs { - prevOutput := &unspent.States[input.PrevIndex].Output - accountState, err := cache.GetAccountStateOrNew(prevOutput.ScriptHash) - if err != nil { - return nil, err - } - - delete(accountState.Balances, prevOutput.AssetID) - if err = cache.PutAccountState(accountState); err != nil { - return nil, err - } - } - } - - switch t := tx.Data.(type) { - case *transaction.EnrollmentTX: - if err := processEnrollmentTX(cache, t); err != nil { - return nil, err - } - case *transaction.StateTX: - if err := bc.processStateTX(cache, tx, t); err != nil { - return nil, err - } - } - } - } - - return bc.contracts.NEO.GetValidatorsInternal(bc, cache) +// GetValidators returns next block validators. +func (bc *Blockchain) GetValidators() ([]*keys.PublicKey, error) { + return bc.contracts.NEO.GetNextBlockValidatorsInternal(bc, bc.dao) } -// GetEnrollments returns all registered validators and non-registered SB validators -func (bc *Blockchain) GetEnrollments() ([]*state.Validator, error) { - validators := bc.dao.GetValidators() - standByValidators, err := bc.GetStandByValidators() - if err != nil { - return nil, err - } - uniqueSBValidators := standByValidators.Unique() - - var result []*state.Validator - for _, validator := range validators { - if validator.Registered { - result = append(result, validator) - } - } - for _, sBValidator := range uniqueSBValidators { - isAdded := false - for _, v := range result { - if v.PublicKey == sBValidator { - isAdded = true - break - } - } - if !isAdded { - result = append(result, &state.Validator{ - PublicKey: sBValidator, - Registered: false, - Votes: 0, - }) - } - } - return result, nil -} - -func (bc *Blockchain) processStateTX(dao *dao.Cached, t *transaction.Transaction, tx *transaction.StateTX) error { - for _, desc := range tx.Descriptors { - switch desc.Type { - case transaction.Account: - if err := bc.processAccountStateDescriptor(desc, t, dao); err != nil { - return err - } - case transaction.Validator: - if err := processValidatorStateDescriptor(desc, dao); err != nil { - return err - } - } - } - return nil -} - -func processEnrollmentTX(dao *dao.Cached, tx *transaction.EnrollmentTX) error { - validatorState, err := dao.GetValidatorStateOrNew(&tx.PublicKey) - if err != nil { - return err - } - validatorState.Registered = true - return dao.PutValidatorState(validatorState) +// GetEnrollments returns all registered validators. +func (bc *Blockchain) GetEnrollments() ([]state.Validator, error) { + return bc.contracts.NEO.GetRegisteredValidators(bc.dao) } // GetScriptHashesForVerifying returns all the ScriptHashes of a transaction which will be use diff --git a/pkg/core/blockchainer/blockchainer.go b/pkg/core/blockchainer/blockchainer.go index 0393a4059..d749ec995 100644 --- a/pkg/core/blockchainer/blockchainer.go +++ b/pkg/core/blockchainer/blockchainer.go @@ -24,7 +24,7 @@ type Blockchainer interface { HeaderHeight() uint32 GetBlock(hash util.Uint256) (*block.Block, error) GetContractState(hash util.Uint160) *state.Contract - GetEnrollments() ([]*state.Validator, error) + GetEnrollments() ([]state.Validator, error) GetHeaderHash(int) util.Uint256 GetHeader(hash util.Uint256) (*block.Header, error) CurrentHeaderHash() util.Uint256 @@ -36,7 +36,7 @@ type Blockchainer interface { GetAppExecResult(util.Uint256) (*state.AppExecResult, error) GetNEP5TransferLog(util.Uint160) *state.NEP5TransferLog GetNEP5Balances(util.Uint160) *state.NEP5Balances - GetValidators(txes ...*transaction.Transaction) ([]*keys.PublicKey, error) + GetValidators() ([]*keys.PublicKey, error) GetStandByValidators() (keys.PublicKeys, error) GetScriptHashesForVerifying(*transaction.Transaction) ([]util.Uint160, error) GetStorageItem(scripthash util.Uint160, key []byte) *state.StorageItem diff --git a/pkg/core/dao/dao.go b/pkg/core/dao/dao.go index 23fab4fc8..f803078a4 100644 --- a/pkg/core/dao/dao.go +++ b/pkg/core/dao/dao.go @@ -10,7 +10,6 @@ import ( "github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/storage" "github.com/nspcc-dev/neo-go/pkg/core/transaction" - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/util" ) @@ -20,7 +19,6 @@ type DAO interface { AppendNEP5Transfer(acc util.Uint160, index uint32, tr *state.NEP5Transfer) (bool, error) DeleteContractState(hash util.Uint160) error DeleteStorageItem(scripthash util.Uint160, key []byte) error - DeleteValidatorState(vs *state.Validator) error GetAccountState(hash util.Uint160) (*state.Account, error) GetAccountStateOrNew(hash util.Uint160) (*state.Account, error) GetAndDecode(entity io.Serializable, key []byte) error @@ -39,9 +37,6 @@ type DAO interface { GetStorageItemsWithPrefix(hash util.Uint160, prefix []byte) (map[string]*state.StorageItem, error) GetTransaction(hash util.Uint256) (*transaction.Transaction, uint32, error) GetUnspentCoinState(hash util.Uint256) (*state.UnspentCoin, error) - GetValidatorState(publicKey *keys.PublicKey) (*state.Validator, error) - GetValidatorStateOrNew(publicKey *keys.PublicKey) (*state.Validator, error) - GetValidators() []*state.Validator GetVersion() (string, error) GetWrapped() DAO HasTransaction(hash util.Uint256) bool @@ -57,7 +52,6 @@ type DAO interface { PutNEP5TransferLog(acc util.Uint160, index uint32, lg *state.NEP5TransferLog) error PutStorageItem(scripthash util.Uint160, key []byte, si *state.StorageItem) error PutUnspentCoinState(hash util.Uint256, ucs *state.UnspentCoin) error - PutValidatorState(vs *state.Validator) error PutVersion(v string) error StoreAsBlock(block *block.Block, sysFee uint32) error StoreAsCurrentBlock(block *block.Block) error @@ -307,61 +301,6 @@ func (dao *Simple) putUnspentCoinState(hash util.Uint256, ucs *state.UnspentCoin // -- end unspent coins. -// -- start validator. - -// GetValidatorStateOrNew gets validator from store or created new one in case of error. -func (dao *Simple) GetValidatorStateOrNew(publicKey *keys.PublicKey) (*state.Validator, error) { - validatorState, err := dao.GetValidatorState(publicKey) - if err != nil { - if err != storage.ErrKeyNotFound { - return nil, err - } - validatorState = &state.Validator{PublicKey: publicKey} - } - return validatorState, nil - -} - -// GetValidators returns all validators from store. -func (dao *Simple) GetValidators() []*state.Validator { - var validators []*state.Validator - dao.Store.Seek(storage.STValidator.Bytes(), func(k, v []byte) { - r := io.NewBinReaderFromBuf(v) - validator := &state.Validator{} - validator.DecodeBinary(r) - if r.Err != nil { - return - } - validators = append(validators, validator) - }) - return validators -} - -// GetValidatorState returns validator by publicKey. -func (dao *Simple) GetValidatorState(publicKey *keys.PublicKey) (*state.Validator, error) { - validatorState := &state.Validator{} - key := storage.AppendPrefix(storage.STValidator, publicKey.Bytes()) - err := dao.GetAndDecode(validatorState, key) - if err != nil { - return nil, err - } - return validatorState, nil -} - -// PutValidatorState puts given Validator into the given store. -func (dao *Simple) PutValidatorState(vs *state.Validator) error { - key := storage.AppendPrefix(storage.STValidator, vs.PublicKey.Bytes()) - return dao.Put(vs, key) -} - -// DeleteValidatorState deletes given Validator into the given store. -func (dao *Simple) DeleteValidatorState(vs *state.Validator) error { - key := storage.AppendPrefix(storage.STValidator, vs.PublicKey.Bytes()) - return dao.Store.Delete(key) -} - -// -- end validator. - // -- start notification event. // GetAppExecResult gets application execution result from the diff --git a/pkg/core/dao/dao_test.go b/pkg/core/dao/dao_test.go index 24ec938f5..65e74b50e 100644 --- a/pkg/core/dao/dao_test.go +++ b/pkg/core/dao/dao_test.go @@ -113,61 +113,6 @@ func TestPutGetUnspentCoinState(t *testing.T) { require.Equal(t, unspentCoinState, gotUnspentCoinState) } -func TestGetValidatorStateOrNew_New(t *testing.T) { - dao := NewSimple(storage.NewMemoryStore()) - publicKey := &keys.PublicKey{} - validatorState, err := dao.GetValidatorStateOrNew(publicKey) - require.NoError(t, err) - require.NotNil(t, validatorState) -} - -func TestPutGetValidatorState(t *testing.T) { - dao := NewSimple(storage.NewMemoryStore()) - publicKey := &keys.PublicKey{} - validatorState := &state.Validator{ - PublicKey: publicKey, - Registered: false, - Votes: 0, - } - err := dao.PutValidatorState(validatorState) - require.NoError(t, err) - gotValidatorState, err := dao.GetValidatorState(publicKey) - require.NoError(t, err) - require.Equal(t, validatorState, gotValidatorState) -} - -func TestDeleteValidatorState(t *testing.T) { - dao := NewSimple(storage.NewMemoryStore()) - publicKey := &keys.PublicKey{} - validatorState := &state.Validator{ - PublicKey: publicKey, - Registered: false, - Votes: 0, - } - err := dao.PutValidatorState(validatorState) - require.NoError(t, err) - err = dao.DeleteValidatorState(validatorState) - require.NoError(t, err) - gotValidatorState, err := dao.GetValidatorState(publicKey) - require.Error(t, err) - require.Nil(t, gotValidatorState) -} - -func TestGetValidators(t *testing.T) { - dao := NewSimple(storage.NewMemoryStore()) - publicKey := &keys.PublicKey{} - validatorState := &state.Validator{ - PublicKey: publicKey, - Registered: false, - Votes: 0, - } - err := dao.PutValidatorState(validatorState) - require.NoError(t, err) - validators := dao.GetValidators() - require.Equal(t, validatorState, validators[0]) - require.Len(t, validators, 1) -} - func TestPutGetAppExecResult(t *testing.T) { dao := NewSimple(storage.NewMemoryStore()) hash := random.Uint256() diff --git a/pkg/core/interop_neo.go b/pkg/core/interop_neo.go index d144891e1..065ecd8e5 100644 --- a/pkg/core/interop_neo.go +++ b/pkg/core/interop_neo.go @@ -236,13 +236,6 @@ func witnessGetVerificationScript(ic *interop.Context, v *vm.VM) error { return nil } -// bcGetValidators returns validators. -func bcGetValidators(ic *interop.Context, v *vm.VM) error { - validators := ic.DAO.GetValidators() - v.Estack().PushVal(validators) - return nil -} - // popInputFromVM returns transaction.Input from the first estack element. func popInputFromVM(v *vm.VM) (*transaction.Input, error) { inInterface := v.Estack().Pop().Value() diff --git a/pkg/core/interops.go b/pkg/core/interops.go index 7a4d276c8..0f2c2c203 100644 --- a/pkg/core/interops.go +++ b/pkg/core/interops.go @@ -139,7 +139,6 @@ var neoInterops = []interop.Function{ {Name: "Neo.Blockchain.GetHeight", Func: bcGetHeight, Price: 1}, {Name: "Neo.Blockchain.GetTransaction", Func: bcGetTransaction, Price: 100}, {Name: "Neo.Blockchain.GetTransactionHeight", Func: bcGetTransactionHeight, Price: 100}, - {Name: "Neo.Blockchain.GetValidators", Func: bcGetValidators, Price: 200}, {Name: "Neo.Contract.Create", Func: contractCreate, Price: 0}, {Name: "Neo.Contract.Destroy", Func: contractDestroy, Price: 1}, {Name: "Neo.Contract.GetScript", Func: contractGetScript, Price: 1}, @@ -225,7 +224,6 @@ var neoInterops = []interop.Function{ {Name: "AntShares.Blockchain.GetHeader", Func: bcGetHeader, Price: 100}, {Name: "AntShares.Blockchain.GetHeight", Func: bcGetHeight, Price: 1}, {Name: "AntShares.Blockchain.GetTransaction", Func: bcGetTransaction, Price: 100}, - {Name: "AntShares.Blockchain.GetValidators", Func: bcGetValidators, Price: 200}, {Name: "AntShares.Contract.Create", Func: contractCreate, Price: 0}, {Name: "AntShares.Contract.Destroy", Func: contractDestroy, Price: 1}, {Name: "AntShares.Contract.GetScript", Func: contractGetScript, Price: 1}, diff --git a/pkg/core/native/native_neo.go b/pkg/core/native/native_neo.go index 41c5a5c6c..f159b18ad 100644 --- a/pkg/core/native/native_neo.go +++ b/pkg/core/native/native_neo.go @@ -31,12 +31,6 @@ type keyWithVotes struct { Votes *big.Int } -// pkeyWithVotes is a deserialized key with votes balance. -type pkeyWithVotes struct { - Key *keys.PublicKey - Votes *big.Int -} - const ( neoSyscallName = "Neo.Native.Tokens.NEO" // NEOTotalSupply is the total amount of NEO in the system. @@ -349,6 +343,24 @@ func (n *NEO) getRegisteredValidators(d dao.DAO) ([]keyWithVotes, error) { return arr, nil } +// GetRegisteredValidators returns current registered validators list with keys +// and votes. +func (n *NEO) GetRegisteredValidators(d dao.DAO) ([]state.Validator, error) { + kvs, err := n.getRegisteredValidators(d) + if err != nil { + return nil, err + } + arr := make([]state.Validator, len(kvs)) + for i := range kvs { + arr[i].Key, err = keys.NewPublicKeyFromBytes([]byte(kvs[i].Key)) + if err != nil { + return nil, err + } + arr[i].Votes = kvs[i].Votes + } + return arr, nil +} + func (n *NEO) getRegisteredValidatorsCall(ic *interop.Context, _ []vm.StackItem) vm.StackItem { validators, err := n.getRegisteredValidators(ic.DAO) if err != nil { @@ -374,18 +386,10 @@ func (n *NEO) GetValidatorsInternal(bc blockchainer.Blockchainer, d dao.DAO) (ke if err != nil { return nil, err } - validatorsBytes, err := n.getRegisteredValidators(d) + validators, err := n.GetRegisteredValidators(d) if err != nil { return nil, err } - validators := make([]pkeyWithVotes, len(validatorsBytes)) - for i := range validatorsBytes { - validators[i].Key, err = keys.NewPublicKeyFromBytes([]byte(validatorsBytes[i].Key)) - if err != nil { - return nil, err - } - validators[i].Votes = validatorsBytes[i].Votes - } sort.Slice(validators, func(i, j int) bool { // The most-voted validators should end up in the front of the list. cmp := validators[i].Votes.Cmp(validators[j].Votes) @@ -446,7 +450,7 @@ func (n *NEO) getNextBlockValidators(ic *interop.Context, _ []vm.StackItem) vm.S func (n *NEO) GetNextBlockValidatorsInternal(bc blockchainer.Blockchainer, d dao.DAO) (keys.PublicKeys, error) { si := d.GetStorageItem(n.Hash, nextValidatorsKey) if si == nil { - return bc.GetStandByValidators() + return n.GetValidatorsInternal(bc, d) } pubs := keys.PublicKeys{} err := pubs.DecodeBytes(si.Value) diff --git a/pkg/core/state/validator.go b/pkg/core/state/validator.go index ecdc8cc67..bdfba6ed1 100644 --- a/pkg/core/state/validator.go +++ b/pkg/core/state/validator.go @@ -1,39 +1,13 @@ package state import ( + "math/big" + "github.com/nspcc-dev/neo-go/pkg/crypto/keys" - "github.com/nspcc-dev/neo-go/pkg/io" - "github.com/nspcc-dev/neo-go/pkg/util" ) -// Validator holds the state of a validator. +// Validator holds the state of a validator (its key and votes balance). type Validator struct { - PublicKey *keys.PublicKey - Registered bool - Votes util.Fixed8 -} - -// RegisteredAndHasVotes returns true or false whether Validator is registered and has votes. -func (vs *Validator) RegisteredAndHasVotes() bool { - return vs.Registered && vs.Votes > util.Fixed8(0) -} - -// UnregisteredAndHasNoVotes returns true when Validator is not registered and has no votes. -func (vs *Validator) UnregisteredAndHasNoVotes() bool { - return !vs.Registered && vs.Votes == 0 -} - -// EncodeBinary encodes Validator to the given BinWriter. -func (vs *Validator) EncodeBinary(bw *io.BinWriter) { - vs.PublicKey.EncodeBinary(bw) - bw.WriteBool(vs.Registered) - vs.Votes.EncodeBinary(bw) -} - -// DecodeBinary decodes Validator from the given BinReader. -func (vs *Validator) DecodeBinary(reader *io.BinReader) { - vs.PublicKey = &keys.PublicKey{} - vs.PublicKey.DecodeBinary(reader) - vs.Registered = reader.ReadBool() - vs.Votes.DecodeBinary(reader) + Key *keys.PublicKey + Votes *big.Int } diff --git a/pkg/core/state/validator_test.go b/pkg/core/state/validator_test.go deleted file mode 100644 index 1136aa189..000000000 --- a/pkg/core/state/validator_test.go +++ /dev/null @@ -1,57 +0,0 @@ -package state - -import ( - "math/big" - "testing" - - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" - "github.com/nspcc-dev/neo-go/pkg/internal/testserdes" - "github.com/nspcc-dev/neo-go/pkg/util" - "github.com/stretchr/testify/require" -) - -func TestValidatorState_DecodeEncodeBinary(t *testing.T) { - state := &Validator{ - PublicKey: &keys.PublicKey{}, - Registered: false, - Votes: util.Fixed8(10), - } - - testserdes.EncodeDecodeBinary(t, state, new(Validator)) -} - -func TestRegisteredAndHasVotes_Registered(t *testing.T) { - state := &Validator{ - PublicKey: &keys.PublicKey{ - X: big.NewInt(1), - Y: big.NewInt(1), - }, - Registered: true, - Votes: 0, - } - require.False(t, state.RegisteredAndHasVotes()) -} - -func TestRegisteredAndHasVotes_RegisteredWithVotes(t *testing.T) { - state := &Validator{ - PublicKey: &keys.PublicKey{ - X: big.NewInt(1), - Y: big.NewInt(1), - }, - Registered: true, - Votes: 1, - } - require.True(t, state.RegisteredAndHasVotes()) -} - -func TestRegisteredAndHasVotes_NotRegisteredWithVotes(t *testing.T) { - state := &Validator{ - PublicKey: &keys.PublicKey{ - X: big.NewInt(1), - Y: big.NewInt(1), - }, - Registered: false, - Votes: 1, - } - require.False(t, state.RegisteredAndHasVotes()) -} diff --git a/pkg/network/helper_test.go b/pkg/network/helper_test.go index 48db395a7..6ef6487aa 100644 --- a/pkg/network/helper_test.go +++ b/pkg/network/helper_test.go @@ -96,13 +96,13 @@ func (chain testChain) GetNEP5TransferLog(util.Uint160) *state.NEP5TransferLog { func (chain testChain) GetNEP5Balances(util.Uint160) *state.NEP5Balances { panic("TODO") } -func (chain testChain) GetValidators(...*transaction.Transaction) ([]*keys.PublicKey, error) { +func (chain testChain) GetValidators() ([]*keys.PublicKey, error) { panic("TODO") } func (chain testChain) GetStandByValidators() (keys.PublicKeys, error) { panic("TODO") } -func (chain testChain) GetEnrollments() ([]*state.Validator, error) { +func (chain testChain) GetEnrollments() ([]state.Validator, error) { panic("TODO") } func (chain testChain) GetScriptHashesForVerifying(*transaction.Transaction) ([]util.Uint160, error) { diff --git a/pkg/rpc/response/result/validator.go b/pkg/rpc/response/result/validator.go index 19c5fefda..37862511d 100644 --- a/pkg/rpc/response/result/validator.go +++ b/pkg/rpc/response/result/validator.go @@ -2,13 +2,12 @@ package result import ( "github.com/nspcc-dev/neo-go/pkg/crypto/keys" - "github.com/nspcc-dev/neo-go/pkg/util" ) // Validator used for the representation of // state.Validator on the RPC Server. type Validator struct { PublicKey keys.PublicKey `json:"publickey"` - Votes util.Fixed8 `json:"votes"` + Votes int64 `json:"votes,string"` Active bool `json:"active"` } diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 38a080746..b4164ef2f 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -815,9 +815,9 @@ func (s *Server) getValidators(_ request.Params) (interface{}, error) { var res []result.Validator for _, v := range enrollments { res = append(res, result.Validator{ - PublicKey: *v.PublicKey, - Votes: v.Votes, - Active: validators.Contains(v.PublicKey), + PublicKey: *v.Key, + Votes: v.Votes.Int64(), + Active: validators.Contains(v.Key), }) } return res, nil