Skip to content

Conversation

@siddharthbaleja7
Copy link

Description

This PR fixes inconsistent decoding of Ethereum addresses from byte slices in the ServiceProviderRegistry and related code, addressing issue #758.

  • Implements DecodeAddressCanonical function matching Solidity's address(uint160(BigEndian.decode(bytes))).
  • Replaces all relevant decoding sites to use this new canonical decoding.
  • Unit testing has been performed locally covering edge cases for the decode function.

Issue

Fixes #758

Please review the decoding logic and scope of changes. Happy to include tests or make adjustments as needed.

@siddharthbaleja7 siddharthbaleja7 requested a review from a team as a code owner November 14, 2025 18:34
t.Errorf("Case 2 failed: Expected %x, got %x", input2, decoded2.Bytes())
}

// Case 3: Input longer than 20 bytes → use last 20 bytes only
Copy link
Collaborator

Choose a reason for hiding this comment

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

don't enumerate comments

func DecodeAddressCanonical(input []byte) common.Address {
b := make([]byte, 20)
inLen := len(input)
if inLen >= 20 {
Copy link
Collaborator

Choose a reason for hiding this comment

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

@siddharthbaleja7
Copy link
Author

@wjmelements done with the changes

// DecodeAddressCapability implements the Solidity behavior of
// address(uint160(BigEndian.decode(input))).
func DecodeAddressCapability(input []byte) common.Address {
// If input is longer, we must take the *head* of the slice first.
Copy link
Collaborator

Choose a reason for hiding this comment

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

t.Errorf("Case 2 (exact) failed: Expected %s, got %s", expected2.Hex(), decoded2.Hex())
}

// Case 3: Input > 20 bytes but <= 32 bytes → use last 20 bytes
Copy link
Collaborator

Choose a reason for hiding this comment

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

t.Errorf("Case 3 (medium) failed: Expected %s, got %s", expected2.Hex(), decoded3.Hex())
}

// Case 4: Input > 32 bytes → take first 32, then last 20 from that
Copy link
Collaborator

Choose a reason for hiding this comment

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

t.Errorf("Case 1 (short) failed: Expected %s, got %s", expected1.Hex(), decoded1.Hex())
}

// Case 2: Exactly 20 bytes input → use as is
Copy link
Collaborator

Choose a reason for hiding this comment

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


// TestDecodeAddressCapability tests the canonical address decoding.
func TestDecodeAddressCapability(t *testing.T) {
// Case 1: Input shorter than 20 bytes → left pad with zeros
Copy link
Collaborator

Choose a reason for hiding this comment

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

// These 8 bytes should be IGNORED (they are after byte 32)
0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
}
// The expected result is the last 20 bytes *of the first 32 bytes*
Copy link
Collaborator

Choose a reason for hiding this comment

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

wrong

Copy link
Collaborator

Choose a reason for hiding this comment

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

Please consult the test cases I provided for you
#758 (comment)

t.Errorf("Case 1 (short) failed: Expected %s, got %s", expected1.Hex(), decoded1.Hex())
}

// Case 2: Exactly 20 bytes input → use as is
Copy link
Collaborator

Choose a reason for hiding this comment

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

just make these into separate test cases instead of cramming them into the same test case

@siddharthbaleja7
Copy link
Author

@wjmelements done with the changes

Copy link
Collaborator

@wjmelements wjmelements left a comment

Choose a reason for hiding this comment

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

Kindly read the instructions more carefully. If you have been using AI, please stop.

0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
}

// The expected result is the last 20 bytes *of the first 32 bytes*, which is expectedAddr
Copy link
Collaborator

Choose a reason for hiding this comment

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

@siddharthbaleja7
Copy link
Author

@wjmelements I’ve pushed the updated changes now.

Just to clarify — I did not use any AI for this. I was a bit confused earlier, so I took some extra time to understand the instructions properly. Everything in this update is written and reviewed by me.

Please let me know if any further adjustments are needed.

@siddharthbaleja7
Copy link
Author

@wjmelements done with the changes

@wjmelements wjmelements merged commit 50ab42c into filecoin-project:pdpv0 Nov 16, 2025
15 checks passed
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.

ServiceProviderRegistry: align on canonical decoding address from bytes

2 participants