state: always deserialize LastGasPerVote

It can be non-zero even if VoteTo is NULL. Fixes state diff with 3.6.0:

  block 41660: value mismatch for key +////xTrvgat3qG/w8hQoD/I4MgUz6rygA==: QQQhAS8hA7yiAAAhAA== vs QQQhAS8hA7yiAAAhB+POSWfBCAE=

Related to #2844.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
This commit is contained in:
Roman Khimov 2023-09-05 23:42:24 +03:00
parent c6850b49d9
commit 9bdf66a5e0
2 changed files with 42 additions and 10 deletions

View file

@ -148,17 +148,17 @@ func (s *NEOBalance) FromStackItem(item stackitem.Item) error {
s.BalanceHeight = uint32(h.Int64()) s.BalanceHeight = uint32(h.Int64())
if _, ok := structItem[2].(stackitem.Null); ok { if _, ok := structItem[2].(stackitem.Null); ok {
s.VoteTo = nil s.VoteTo = nil
return nil } else {
bs, err := structItem[2].TryBytes()
if err != nil {
return fmt.Errorf("invalid public key stackitem: %w", err)
}
pub, err := keys.NewPublicKeyFromBytes(bs, elliptic.P256())
if err != nil {
return fmt.Errorf("invalid public key bytes: %w", err)
}
s.VoteTo = pub
} }
bs, err := structItem[2].TryBytes()
if err != nil {
return fmt.Errorf("invalid public key stackitem: %w", err)
}
pub, err := keys.NewPublicKeyFromBytes(bs, elliptic.P256())
if err != nil {
return fmt.Errorf("invalid public key bytes: %w", err)
}
s.VoteTo = pub
if len(structItem) >= 4 { if len(structItem) >= 4 {
lastGasPerVote, err := structItem[3].TryInteger() lastGasPerVote, err := structItem[3].TryInteger()
if err != nil { if err != nil {

View file

@ -1,8 +1,10 @@
package state package state
import ( import (
"math/big"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -47,6 +49,36 @@ func TestNEP17BalanceFromBytesInvalid(t *testing.T) {
require.Error(t, err) require.Error(t, err)
} }
func TestNEOBalanceSerialization(t *testing.T) {
var b = NEOBalance{
NEP17Balance: NEP17Balance{*big.NewInt(100500)},
BalanceHeight: 42,
}
si, err := b.ToStackItem()
require.NoError(t, err)
var bb NEOBalance
require.NoError(t, bb.FromStackItem(si))
require.Equal(t, b, bb)
b.VoteTo, err = keys.NewPublicKeyFromString("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c")
require.NoError(t, err)
b.LastGasPerVote = *big.NewInt(100500)
si, err = b.ToStackItem()
require.NoError(t, err)
bb = NEOBalance{}
require.NoError(t, bb.FromStackItem(si))
require.Equal(t, b, bb)
b.VoteTo = nil
si, err = b.ToStackItem()
require.NoError(t, err)
bb = NEOBalance{}
require.NoError(t, bb.FromStackItem(si))
require.Equal(t, b, bb)
}
func BenchmarkNEP17BalanceBytes(b *testing.B) { func BenchmarkNEP17BalanceBytes(b *testing.B) {
var bl NEP17Balance var bl NEP17Balance
bl.Balance.SetInt64(0x12345678910) bl.Balance.SetInt64(0x12345678910)