Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changelog/1230.bugfix.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
analyzer/runtime: Fix pointer comparison in balance update check

The condition `change != big.NewInt(0)` was comparing pointers instead
of values, causing it to always be true. Changed to `change.Sign() != 0`
for proper value comparison.
5 changes: 5 additions & 0 deletions .changelog/1230.bugfix.2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
common: Fix NumericToBigInt returning zero for negative exponents

The function was returning `*big0` instead of `*bi` for negative
exponents, causing it to always return zero. Added tests for the
function.
2 changes: 1 addition & 1 deletion analyzer/runtime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,7 @@ func (m *processor) queueDbUpdates(batch *storage.QueryBatch, data *BlockData) {
// Update EVM token balances (dead reckoning).
for key, change := range data.TokenBalanceChanges {
// Update (dead-reckon) the DB balance only if it's actually changed.
if change != big.NewInt(0) && m.mode != analyzer.FastSyncMode {
if change.Sign() != 0 && m.mode != analyzer.FastSyncMode {
if key.TokenAddress == evm.NativeRuntimeTokenAddress {
batch.Queue(queries.RuntimeNativeBalanceUpsert, m.runtime, key.AccountAddress, nativeTokenSymbol(m.sdkPT), change.String())
} else {
Expand Down
4 changes: 2 additions & 2 deletions common/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,9 @@ func NumericToBigInt(n pgtype.Numeric) (BigInt, error) {
remainder := &big.Int{}
bi.DivMod(bi, div, remainder)
if remainder.Cmp(big0) != 0 {
return BigInt{Int: *big0}, fmt.Errorf("cannot convert %v to integer", n)
return BigInt{}, fmt.Errorf("cannot convert %v to integer", n)
}
return BigInt{Int: *big0}, nil
return BigInt{Int: *bi}, nil
}

// Decimal is a wrapper around apd.Decimal to allow for custom JSON marshaling.
Expand Down
52 changes: 52 additions & 0 deletions common/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import (
"encoding/json"
"fmt"
"math"
"math/big"
"testing"

"github.com/jackc/pgx/v5/pgtype"
"github.com/oasisprotocol/oasis-core/go/common/cbor"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -122,3 +124,53 @@ func TestBigDecimalNumeric(t *testing.T) {
require.EqualValues(t, dec, roundTripped, "BigDecimal should match after Numeric conversion for value %s", tc.value)
}
}

func TestNumericToBigInt(t *testing.T) {
for _, tc := range []struct {
name string
numeric pgtype.Numeric
expected int64
hasError bool
}{
{
name: "zero exponent",
numeric: pgtype.Numeric{Int: big.NewInt(12345), Exp: 0, Valid: true},
expected: 12345,
},
{
name: "positive exponent",
numeric: pgtype.Numeric{Int: big.NewInt(123), Exp: 2, Valid: true},
expected: 12300,
},
{
name: "negative exponent exact division",
numeric: pgtype.Numeric{Int: big.NewInt(12300), Exp: -2, Valid: true},
expected: 123,
},
{
name: "negative exponent with remainder",
numeric: pgtype.Numeric{Int: big.NewInt(12345), Exp: -2, Valid: true},
hasError: true,
},
{
name: "zero value",
numeric: pgtype.Numeric{Int: big.NewInt(0), Exp: 0, Valid: true},
expected: 0,
},
{
name: "negative value",
numeric: pgtype.Numeric{Int: big.NewInt(-500), Exp: 1, Valid: true},
expected: -5000,
},
} {
t.Run(tc.name, func(t *testing.T) {
result, err := NumericToBigInt(tc.numeric)
if tc.hasError {
require.Error(t, err)
} else {
require.NoError(t, err)
require.Equal(t, tc.expected, result.Int64())
}
})
}
}
Loading