Merge pull request #2478 from nspcc-dev/mainnet-fixes

Mainnet fixes
This commit is contained in:
Roman Khimov 2022-05-12 10:04:53 +03:00 committed by GitHub
commit c6f8c33e66
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 9 deletions

View file

@ -2,6 +2,20 @@
This document outlines major changes between releases. This document outlines major changes between releases.
## 0.98.4 "Mesmerization" (11 May 2022)
An urgent release to fix incompatibility with mainnet at block 1528989. The
actual pair of problems leading to inability to process this block occurred
earilier than that, so to fix this you need to resynchronize your node. Fixed
node is confirmed to have identical state as 3.1.0 C# node up to block
1529810.
Bugs fixed:
* StdLib itoa() implementation emitted uppercase letters instead of lowercase
(#2478)
* StdLib jsonDeserialize() implementation couldn't handle properly integers
larger than 64-bit signed (#2478)
## 0.98.3 "Liquidation" (07 May 2022) ## 0.98.3 "Liquidation" (07 May 2022)
This is a hotfix release to fix t4 testnet incompatibility at block This is a hotfix release to fix t4 testnet incompatibility at block

View file

@ -238,7 +238,6 @@ func (s *Std) itoa(_ *interop.Context, args []stackitem.Item) stackitem.Item {
if pad := bs[0] & 0xF8; pad == 0 || pad == 0xF8 { if pad := bs[0] & 0xF8; pad == 0 || pad == 0xF8 {
str = str[1:] str = str[1:]
} }
str = strings.ToUpper(str)
default: default:
panic(ErrInvalidBase) panic(ErrInvalidBase)
} }

View file

@ -35,9 +35,9 @@ func TestStdLibItoaAtoi(t *testing.T) {
{big.NewInt(1), big.NewInt(16), "1"}, {big.NewInt(1), big.NewInt(16), "1"},
{big.NewInt(7), big.NewInt(16), "7"}, {big.NewInt(7), big.NewInt(16), "7"},
{big.NewInt(8), big.NewInt(16), "08"}, {big.NewInt(8), big.NewInt(16), "08"},
{big.NewInt(65535), big.NewInt(16), "0FFFF"}, {big.NewInt(65535), big.NewInt(16), "0ffff"},
{big.NewInt(15), big.NewInt(16), "0F"}, {big.NewInt(15), big.NewInt(16), "0f"},
{big.NewInt(-1), big.NewInt(16), "F"}, {big.NewInt(-1), big.NewInt(16), "f"},
} }
for _, tc := range testCases { for _, tc := range testCases {

View file

@ -7,9 +7,9 @@ import (
"errors" "errors"
"fmt" "fmt"
gio "io" gio "io"
"math"
"math/big" "math/big"
"strconv" "strconv"
"strings"
) )
// decoder is a wrapper around json.Decoder helping to mimic C# json decoder behavior. // decoder is a wrapper around json.Decoder helping to mimic C# json decoder behavior.
@ -164,6 +164,7 @@ func FromJSON(data []byte, maxCount int) (Item, error) {
Decoder: *json.NewDecoder(bytes.NewReader(data)), Decoder: *json.NewDecoder(bytes.NewReader(data)),
count: maxCount, count: maxCount,
} }
d.UseNumber()
if item, err := d.decode(); err != nil { if item, err := d.decode(); err != nil {
return nil, err return nil, err
} else if _, err := d.Token(); err != gio.EOF { } else if _, err := d.Token(); err != gio.EOF {
@ -208,11 +209,24 @@ func (d *decoder) decode() (Item, error) {
} }
case string: case string:
return NewByteArray([]byte(t)), nil return NewByteArray([]byte(t)), nil
case float64: case json.Number:
if math.Floor(t) != t { ts := t.String()
dot := strings.IndexByte(ts, '.')
if dot != -1 {
// As a special case numbers like 123.000 are allowed (SetString rejects them).
// And yes, that's the way C# code works also.
for _, r := range ts[dot+1:] {
if r != '0' {
return nil, fmt.Errorf("%w (real value for int)", ErrInvalidValue) return nil, fmt.Errorf("%w (real value for int)", ErrInvalidValue)
} }
return NewBigInteger(big.NewInt(int64(t))), nil }
ts = ts[:dot]
}
num, ok := new(big.Int).SetString(ts, 10)
if !ok {
return nil, fmt.Errorf("%w (integer)", ErrInvalidValue)
}
return NewBigInteger(num), nil
case bool: case bool:
return NewBool(t), nil return NewBool(t), nil
default: default: