Skip to content

Commit

Permalink
fix: handling for long addresses (#520)
Browse files Browse the repository at this point in the history
Fixes #519
  • Loading branch information
agaffney committed Mar 9, 2024
1 parent 96631ad commit 9f9589f
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 7 deletions.
39 changes: 33 additions & 6 deletions ledger/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ type Address struct {
networkId uint8
paymentAddress []byte
stakingAddress []byte
extraData []byte
}

// NewAddress returns an Address based on the provided bech32 address string
Expand All @@ -236,16 +237,32 @@ func NewAddressFromParts(
networkId uint8,
paymentAddr []byte,
stakingAddr []byte,
) Address {
) (Address, error) {
if len(paymentAddr) != AddressHashSize {
return Address{}, fmt.Errorf("invalid payment address hash length: %d", len(paymentAddr))
}
if len(stakingAddr) > 0 && len(stakingAddr) != AddressHashSize {
return Address{}, fmt.Errorf("invalid staking address hash length: %d", len(stakingAddr))
}
return Address{
addressType: addrType,
networkId: networkId,
paymentAddress: paymentAddr,
stakingAddress: stakingAddr,
}
paymentAddress: paymentAddr[:],
stakingAddress: stakingAddr[:],
}, nil
}

func (a *Address) populateFromBytes(data []byte) {
func (a *Address) populateFromBytes(data []byte) error {
// Check length
dataLen := len(data)
if dataLen < (AddressHashSize + 1) {
return fmt.Errorf("invalid address length: %d", dataLen)
}
if dataLen > (AddressHashSize + 1) {
if dataLen < (AddressHashSize + AddressHashSize + 1) {
return fmt.Errorf("invalid address length: %d", dataLen)
}
}
// Extract header info
header := data[0]
a.addressType = (header & AddressHeaderTypeMask) >> 4
Expand All @@ -254,13 +271,22 @@ func (a *Address) populateFromBytes(data []byte) {
// NOTE: this is probably incorrect for Byron
payload := data[1:]
a.paymentAddress = payload[:AddressHashSize]
a.stakingAddress = payload[AddressHashSize:]
if len(payload) > AddressHashSize {
a.stakingAddress = payload[AddressHashSize : AddressHashSize+AddressHashSize]
}
// Store any extra address data
// This is needed to handle the case describe in:
// https://github.com/IntersectMBO/cardano-ledger/issues/2729
if len(payload) > (AddressHashSize + AddressHashSize) {
a.extraData = payload[AddressHashSize+AddressHashSize:]
}
// Adjust stake addresses
if a.addressType == AddressTypeNoneKey ||
a.addressType == AddressTypeNoneScript {
a.stakingAddress = a.paymentAddress[:]
a.paymentAddress = make([]byte, 0)
}
return nil
}

func (a *Address) UnmarshalCBOR(data []byte) error {
Expand Down Expand Up @@ -344,6 +370,7 @@ func (a Address) Bytes() []byte {
)
ret = append(ret, a.paymentAddress...)
ret = append(ret, a.stakingAddress...)
ret = append(ret, a.extraData...)
return ret
}

Expand Down
11 changes: 10 additions & 1 deletion ledger/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ func TestAddressFromBytes(t *testing.T) {
addressBytesHex: "61cfe224295a282d69edda5fa8de4f131e2b9cd21a6c9235597fa4ff6b",
expectedAddress: "addr1v887yfpftg5z660dmf063hj0zv0zh8xjrfkfyd2e07j076cecha5k",
},
// Long (but apparently valid) address from:
// https://github.com/IntersectMBO/cardano-ledger/issues/2729
{
addressBytesHex: "015bad085057ac10ecc7060f7ac41edd6f63068d8963ef7d86ca58669e5ecf2d283418a60be5a848a2380eb721000da1e0bbf39733134beca4cb57afb0b35fc89c63061c9914e055001a518c7516",
expectedAddress: "addr1q9d66zzs27kppmx8qc8h43q7m4hkxp5d39377lvxefvxd8j7eukjsdqc5c97t2zg5guqadepqqx6rc9m7wtnxy6tajjvk4a0kze4ljyuvvrpexg5up2sqxj33363v35gtew",
},
}
for _, testDef := range testDefs {
addr := Address{}
Expand Down Expand Up @@ -197,12 +203,15 @@ func TestAddressFromParts(t *testing.T) {
},
}
for _, testDef := range testDefs {
addr := NewAddressFromParts(
addr, err := NewAddressFromParts(
testDef.addressType,
testDef.networkId,
testDef.paymentAddr,
testDef.stakingAddr,
)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
if addr.String() != testDef.expectedAddress {
t.Fatalf(
"address did not match expected value, got: %s, wanted: %s",
Expand Down

0 comments on commit 9f9589f

Please sign in to comment.