Skip to content

refactor(collections): add UintValueEncoder and use Uint for wei store#2595

Open
expertdicer wants to merge 1 commit into
mainfrom
expertdicer/collections-uint-value-encoder
Open

refactor(collections): add UintValueEncoder and use Uint for wei store#2595
expertdicer wants to merge 1 commit into
mainfrom
expertdicer/collections-uint-value-encoder

Conversation

@expertdicer
Copy link
Copy Markdown
Contributor

Abstract

collections.IntValueEncoder used to delegate to IntKeyEncoder, which panics on negative or nil sdkmath.Int values. That was misleading for signed state (e.g. wei block deltas) and unsafe for callers that expected a general signed int encoder.

This PR splits signed value encoding from unsigned fixed-width encoding: IntValueEncoder now marshals signed sdkmath.Int, a new UintValueEncoder keeps the existing 32-byte big-endian format for non-negative persisted state, and weiStore is typed as sdkmath.Uint. eth.SignedIntValueEncoder is removed in favor of the generic collections encoder.

@expertdicer expertdicer requested a review from a team as a code owner May 27, 2026 07:25
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the weiStore balance tracking in the bank keeper to use sdkmath.Uint instead of sdkmath.Int, introducing a new UintValueEncoder in the x/collections module. It also removes the custom SignedIntValueEncoder from the eth package, standardizing on collections.IntValueEncoder. The review identified two issues: a potential nil pointer dereference in setWeiStoreBalance due to the order of conditions in an equality check, and a potential slice bounds out of range panic in encodeFixedWidthUnsignedBigEndian if the big integer exceeds 256 bits.

}

k.weiStore.Insert(ctx, addr, sdkmath.NewIntFromBigInt(newStoreBal.ToBig()))
k.weiStore.Insert(ctx, addr, sdkmath.NewUintFromBigInt(newStoreBal.ToBig()))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

In setWeiStoreBalance, there is a potential nil pointer dereference panic at line 294:

if weiStoreBalPre.Eq(newStoreBal) || newStoreBal == nil {

If newStoreBal is nil (which can happen when setNibiBalanceFromWei is called with a nil wei balance), weiStoreBalPre.Eq(newStoreBal) is evaluated first. Since newStoreBal is nil, calling Eq on it will dereference a nil pointer and panic.

To fix this, the nil check newStoreBal == nil must be placed before weiStoreBalPre.Eq(newStoreBal) to leverage short-circuit evaluation:

if newStoreBal == nil || weiStoreBalPre.Eq(newStoreBal) {

Comment on lines +162 to 167
func encodeFixedWidthUnsignedBigEndian(i *big.Int) []byte {
be := i.Bytes()
padded := make([]byte, maxIntKeyLen)
copy(padded[maxIntKeyLen-len(be):], be)
return padded
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If i is larger than 256 bits, len(be) will exceed maxIntKeyLen (32). This will cause maxIntKeyLen - len(be) to be negative, resulting in a cryptic runtime slice bounds out of range panic when slicing padded.

Adding an explicit overflow check with a clear panic message improves robustness and makes debugging much easier.

func encodeFixedWidthUnsignedBigEndian(i *big.Int) []byte {
	be := i.Bytes()
	if len(be) > maxIntKeyLen {
		panic(fmt.Sprintf("value overflows max bit length of %d bits", sdkmath.MaxBitLen))
	}
	padded := make([]byte, maxIntKeyLen)
	copy(padded[maxIntKeyLen-len(be):], be)
	return padded
}

@codecov
Copy link
Copy Markdown

codecov Bot commented May 27, 2026

Codecov Report

❌ Patch coverage is 75.67568% with 9 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
x/collections/value_encoder.go 67.85% 7 Missing and 2 partials ⚠️

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug] The IntKeyEncoder.Encode function panics if the input math.Int is nil or negative.

1 participant