fix(types): cache address prefix for integrated detection
Some checks are pending
Security Scan / security (push) Waiting to run
Test / Test (push) Waiting to run

Co-Authored-By: Charon <charon@lethean.io>
This commit is contained in:
Virgil 2026-04-04 18:13:10 +00:00
parent 1db746cbe8
commit 5f48253f59
2 changed files with 32 additions and 5 deletions

View file

@ -31,6 +31,7 @@ type Address struct {
SpendPublicKey PublicKey
ViewPublicKey PublicKey
Flags uint8
prefix uint64
}
// IsAuditable reports whether the address has the auditable flag set.
@ -41,11 +42,7 @@ func (a *Address) IsAuditable() bool {
// IsIntegrated reports whether the given prefix corresponds to an integrated
// address type (standard integrated or auditable integrated).
func (a *Address) IsIntegrated() bool {
// This method checks whether the address was decoded with an integrated
// prefix. Since we do not store the prefix in the Address struct, callers
// should use the prefix returned by DecodeAddress to determine this.
// This helper exists for convenience when the prefix is not available.
return false
return IsIntegratedPrefix(a.prefix)
}
// IsIntegratedPrefix reports whether the given prefix corresponds to an
@ -62,6 +59,8 @@ func IsIntegratedPrefix(prefix uint64) bool {
//
// The checksum is the first 4 bytes of Keccak-256 over the preceding data.
func (a *Address) Encode(prefix uint64) string {
a.prefix = prefix
// Build the raw data: prefix (varint) + keys + flags.
prefixBytes := encodeVarint(prefix)
raw := make([]byte, 0, len(prefixBytes)+32+32+1+4)
@ -117,6 +116,7 @@ func DecodeAddress(s string) (*Address, uint64, error) {
copy(addr.SpendPublicKey[:], remaining[0:32])
copy(addr.ViewPublicKey[:], remaining[32:64])
addr.Flags = remaining[64]
addr.prefix = prefix
return addr, prefix, nil
}

View file

@ -65,6 +65,10 @@ func TestAddressEncodeDecodeRoundTrip_Good(t *testing.T) {
if decoded.Flags != original.Flags {
t.Errorf("Flags mismatch: got 0x%02x, want 0x%02x", decoded.Flags, original.Flags)
}
if decoded.IsIntegrated() != IsIntegratedPrefix(tt.prefix) {
t.Errorf("IsIntegrated mismatch: got %v, want %v", decoded.IsIntegrated(), IsIntegratedPrefix(tt.prefix))
}
})
}
}
@ -103,6 +107,29 @@ func TestIsIntegratedPrefix_Good(t *testing.T) {
}
}
func TestAddressIsIntegrated_Good(t *testing.T) {
tests := []struct {
name string
prefix uint64
want bool
}{
{"standard", config.AddressPrefix, false},
{"integrated", config.IntegratedAddressPrefix, true},
{"auditable", config.AuditableAddressPrefix, false},
{"auditable_integrated", config.AuditableIntegratedAddressPrefix, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
addr := makeTestAddress(0)
addr.Encode(tt.prefix)
if got := addr.IsIntegrated(); got != tt.want {
t.Errorf("IsIntegrated: got %v, want %v", got, tt.want)
}
})
}
}
func TestDecodeAddress_Bad(t *testing.T) {
tests := []struct {
name string