From 9bdf66a5e0dd14e11c9c3df0ef504aa6f9ea18b5 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Tue, 5 Sep 2023 23:42:24 +0300 Subject: [PATCH] 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 --- pkg/core/state/native_state.go | 20 +++++++++--------- pkg/core/state/native_state_test.go | 32 +++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/pkg/core/state/native_state.go b/pkg/core/state/native_state.go index 5e4d7c4c3..fd93f7a27 100644 --- a/pkg/core/state/native_state.go +++ b/pkg/core/state/native_state.go @@ -148,17 +148,17 @@ func (s *NEOBalance) FromStackItem(item stackitem.Item) error { s.BalanceHeight = uint32(h.Int64()) if _, ok := structItem[2].(stackitem.Null); ok { 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 { lastGasPerVote, err := structItem[3].TryInteger() if err != nil { diff --git a/pkg/core/state/native_state_test.go b/pkg/core/state/native_state_test.go index 6cb6f4a61..a1b403748 100644 --- a/pkg/core/state/native_state_test.go +++ b/pkg/core/state/native_state_test.go @@ -1,8 +1,10 @@ package state import ( + "math/big" "testing" + "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/stretchr/testify/require" ) @@ -47,6 +49,36 @@ func TestNEP17BalanceFromBytesInvalid(t *testing.T) { 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) { var bl NEP17Balance bl.Balance.SetInt64(0x12345678910)