mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-26 19:42:23 +00:00
native: fix getvalidators to match C# implementation
ValidatorsCount is not initialized at block 0 with C# node (the first voter initializes it) and until that initialization happens the standby validators list is being returned as is without sorting. Fixes state mismatch for the key ffffffff0e00000000000000000000000000000001 in the first blocks. It also affects tests as now the first validator is different and it receives the network fees.
This commit is contained in:
parent
66df805f3b
commit
2f8e7e4d33
4 changed files with 36 additions and 24 deletions
|
@ -213,7 +213,7 @@ func newTestService(t *testing.T) *service {
|
|||
}
|
||||
|
||||
func getTestValidator(i int) (*privateKey, *publicKey) {
|
||||
key := testchain.PrivateKey(i)
|
||||
key := testchain.PrivateKeyByID(i)
|
||||
return &privateKey{PrivateKey: key}, &publicKey{PublicKey: key.PublicKey()}
|
||||
}
|
||||
|
||||
|
@ -241,9 +241,8 @@ func signTx(t *testing.T, feePerByte util.Fixed8, txs ...*transaction.Transactio
|
|||
validators := make([]*keys.PublicKey, 4)
|
||||
privNetKeys := make([]*keys.PrivateKey, 4)
|
||||
for i := 0; i < 4; i++ {
|
||||
privateKey, publicKey := getTestValidator(i)
|
||||
validators[i] = publicKey.PublicKey
|
||||
privNetKeys[i] = privateKey.PrivateKey
|
||||
privNetKeys[i] = testchain.PrivateKey(i)
|
||||
validators[i] = privNetKeys[i].PublicKey()
|
||||
}
|
||||
rawScript, err := smartcontract.CreateMultiSigRedeemScript(3, validators)
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -210,7 +210,7 @@ func TestCreateBasicChain(t *testing.T) {
|
|||
t.Logf("txMoveNeo: %s", txMoveNeo.Hash().StringLE())
|
||||
t.Logf("txMoveGas: %s", txMoveGas.Hash().StringLE())
|
||||
|
||||
require.Equal(t, util.Fixed8FromInt64(1000), bc.GetUtilityTokenBalance(priv0ScriptHash))
|
||||
require.True(t, util.Fixed8FromInt64(1000).CompareTo(bc.GetUtilityTokenBalance(priv0ScriptHash)) <= 0)
|
||||
// info for getblockheader rpc tests
|
||||
t.Logf("header hash: %s", b.Hash().StringLE())
|
||||
buf := io.NewBufBinWriter()
|
||||
|
|
|
@ -112,8 +112,6 @@ func NewNEO() *NEO {
|
|||
|
||||
// Initialize initializes NEO contract.
|
||||
func (n *NEO) Initialize(ic *interop.Context) error {
|
||||
var si state.StorageItem
|
||||
|
||||
if err := n.nep5TokenNative.Initialize(ic); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -122,11 +120,6 @@ func (n *NEO) Initialize(ic *interop.Context) error {
|
|||
return errors.New("already initialized")
|
||||
}
|
||||
|
||||
vc := new(ValidatorsCount)
|
||||
si.Value = vc.Bytes()
|
||||
if err := ic.DAO.PutStorageItem(n.ContractID, validatorsCountKey, &si); err != nil {
|
||||
return err
|
||||
}
|
||||
h, vs, err := getStandbyValidatorsHash(ic)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -284,14 +277,21 @@ func (n *NEO) VoteInternal(ic *interop.Context, h util.Uint160, pubs keys.Public
|
|||
newPubs = append(newPubs, pub)
|
||||
}
|
||||
if lp, lv := len(newPubs), len(acc.Votes); lp != lv {
|
||||
si := ic.DAO.GetStorageItem(n.ContractID, validatorsCountKey)
|
||||
var si *state.StorageItem
|
||||
var vc *ValidatorsCount
|
||||
var err error
|
||||
|
||||
si = ic.DAO.GetStorageItem(n.ContractID, validatorsCountKey)
|
||||
if si == nil {
|
||||
return errors.New("validators count uninitialized")
|
||||
}
|
||||
vc, err := ValidatorsCountFromBytes(si.Value)
|
||||
// The first voter.
|
||||
si = new(state.StorageItem)
|
||||
vc = new(ValidatorsCount)
|
||||
} else {
|
||||
vc, err = ValidatorsCountFromBytes(si.Value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if lv > 0 {
|
||||
vc[lv-1].Sub(&vc[lv-1], &acc.Balance)
|
||||
}
|
||||
|
@ -384,9 +384,13 @@ func (n *NEO) getRegisteredValidatorsCall(ic *interop.Context, _ []stackitem.Ite
|
|||
|
||||
// GetValidatorsInternal returns a list of current validators.
|
||||
func (n *NEO) GetValidatorsInternal(bc blockchainer.Blockchainer, d dao.DAO) (keys.PublicKeys, error) {
|
||||
standByValidators, err := bc.GetStandByValidators()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
si := d.GetStorageItem(n.ContractID, validatorsCountKey)
|
||||
if si == nil {
|
||||
return nil, errors.New("validators count uninitialized")
|
||||
return standByValidators, nil
|
||||
}
|
||||
validatorsCount, err := ValidatorsCountFromBytes(si.Value)
|
||||
if err != nil {
|
||||
|
@ -407,10 +411,6 @@ func (n *NEO) GetValidatorsInternal(bc blockchainer.Blockchainer, d dao.DAO) (ke
|
|||
})
|
||||
|
||||
count := validatorsCount.GetWeightedAverage()
|
||||
standByValidators, err := bc.GetStandByValidators()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if count < len(standByValidators) {
|
||||
count = len(standByValidators)
|
||||
}
|
||||
|
|
|
@ -147,7 +147,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
},
|
||||
{
|
||||
Asset: e.chain.UtilityTokenHash(),
|
||||
Amount: "923.96937740",
|
||||
Amount: "924.01732700",
|
||||
LastUpdated: 6,
|
||||
}},
|
||||
Address: testchain.PrivateKeyByID(0).GetScriptHash().StringLE(),
|
||||
|
@ -259,6 +259,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
// take burned gas into account
|
||||
u := testchain.PrivateKeyByID(0).GetScriptHash()
|
||||
for i := 0; i <= int(e.chain.BlockHeight()); i++ {
|
||||
var netFee util.Fixed8
|
||||
h := e.chain.GetHeaderHash(i)
|
||||
b, err := e.chain.GetBlock(h)
|
||||
require.NoError(t, err)
|
||||
|
@ -274,7 +275,19 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
TxHash: b.Hash(),
|
||||
})
|
||||
}
|
||||
netFee += b.Transactions[j].NetworkFee
|
||||
}
|
||||
if i > 0 {
|
||||
expected.Received = append(expected.Received, result.NEP5Transfer{
|
||||
Timestamp: b.Timestamp,
|
||||
Asset: e.chain.UtilityTokenHash(),
|
||||
Address: "", // minted from network fees.
|
||||
Amount: amountToString(int64(netFee), 8),
|
||||
Index: b.Index,
|
||||
TxHash: b.Hash(),
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
require.Equal(t, expected.Address, res.Address)
|
||||
require.ElementsMatch(t, expected.Sent, res.Sent)
|
||||
|
|
Loading…
Reference in a new issue