-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
R4R: Bech32 Empty Addresses #2601
Changes from all commits
2720883
bdce019
cef9ea2
2039080
0090817
0f92f6a
7cdcc7a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ import ( | |
"encoding/json" | ||
"errors" | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/tendermint/tendermint/crypto" | ||
"github.com/tendermint/tendermint/crypto/encoding/amino" | ||
|
@@ -71,12 +72,21 @@ func AccAddressFromHex(address string) (addr AccAddress, err error) { | |
|
||
// AccAddressFromBech32 creates an AccAddress from a Bech32 string. | ||
func AccAddressFromBech32(address string) (addr AccAddress, err error) { | ||
if len(strings.TrimSpace(address)) == 0 { | ||
return AccAddress{}, nil | ||
} | ||
|
||
bech32PrefixAccAddr := GetConfig().GetBech32AccountAddrPrefix() | ||
|
||
bz, err := GetFromBech32(address, bech32PrefixAccAddr) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if len(bz) != AddrLen { | ||
return nil, errors.New("Incorrect address length") | ||
} | ||
|
||
return AccAddress(bz), nil | ||
} | ||
|
||
|
@@ -141,7 +151,12 @@ func (aa AccAddress) Bytes() []byte { | |
|
||
// String implements the Stringer interface. | ||
func (aa AccAddress) String() string { | ||
if aa.Empty() { | ||
return "" | ||
} | ||
|
||
bech32PrefixAccAddr := GetConfig().GetBech32AccountAddrPrefix() | ||
|
||
bech32Addr, err := bech32.ConvertAndEncode(bech32PrefixAccAddr, aa.Bytes()) | ||
if err != nil { | ||
panic(err) | ||
|
@@ -187,12 +202,21 @@ func ValAddressFromHex(address string) (addr ValAddress, err error) { | |
|
||
// ValAddressFromBech32 creates a ValAddress from a Bech32 string. | ||
func ValAddressFromBech32(address string) (addr ValAddress, err error) { | ||
if len(strings.TrimSpace(address)) == 0 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above. |
||
return ValAddress{}, nil | ||
} | ||
|
||
bech32PrefixValAddr := GetConfig().GetBech32ValidatorAddrPrefix() | ||
|
||
bz, err := GetFromBech32(address, bech32PrefixValAddr) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if len(bz) != AddrLen { | ||
return nil, errors.New("Incorrect address length") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can this common error live somewhere? |
||
} | ||
|
||
return ValAddress(bz), nil | ||
} | ||
|
||
|
@@ -258,7 +282,12 @@ func (va ValAddress) Bytes() []byte { | |
|
||
// String implements the Stringer interface. | ||
func (va ValAddress) String() string { | ||
if va.Empty() { | ||
return "" | ||
} | ||
|
||
bech32PrefixValAddr := GetConfig().GetBech32ValidatorAddrPrefix() | ||
|
||
bech32Addr, err := bech32.ConvertAndEncode(bech32PrefixValAddr, va.Bytes()) | ||
if err != nil { | ||
panic(err) | ||
|
@@ -304,12 +333,21 @@ func ConsAddressFromHex(address string) (addr ConsAddress, err error) { | |
|
||
// ConsAddressFromBech32 creates a ConsAddress from a Bech32 string. | ||
func ConsAddressFromBech32(address string) (addr ConsAddress, err error) { | ||
if len(strings.TrimSpace(address)) == 0 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above. |
||
return ConsAddress{}, nil | ||
} | ||
|
||
bech32PrefixConsAddr := GetConfig().GetBech32ConsensusAddrPrefix() | ||
|
||
bz, err := GetFromBech32(address, bech32PrefixConsAddr) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if len(bz) != AddrLen { | ||
return nil, errors.New("Incorrect address length") | ||
} | ||
|
||
return ConsAddress(bz), nil | ||
} | ||
|
||
|
@@ -380,7 +418,12 @@ func (ca ConsAddress) Bytes() []byte { | |
|
||
// String implements the Stringer interface. | ||
func (ca ConsAddress) String() string { | ||
if ca.Empty() { | ||
return "" | ||
} | ||
|
||
bech32PrefixConsAddr := GetConfig().GetBech32ConsensusAddrPrefix() | ||
|
||
bech32Addr, err := bech32.ConvertAndEncode(bech32PrefixConsAddr, ca.Bytes()) | ||
if err != nil { | ||
panic(err) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we sure we want to do this direction too (decoding empty strings as valid bech32-addresses)? That seems like it could lead to UX confusion or griefing (tricking users into sending coins to empty addresses, for example).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. @sunnya97 what's the new empty address in bech32 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That should be caught by the
ValidateBasic
of the Msgs.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like its reasonable to make all msg types ensure that the address is
tmhash.size
digest in their validate basics.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really, that seems kinda annoying, why not ensure it at the type level instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets make a new issue for this though, its basically entirely independent of this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't quite follow - I'm concerned about this particular addition, which will accept
""
(the empty string) as a valid bech32-address. Previously that wasn't the case, and any address when de-serialized inGetFromBech32
would be automatically checked for the correct length and checksum. Addresses can still be[]byte
, that's not my concern.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think the more underlying problem is that check tx may pass a tx with invalid address. That should ideally be caught asap. Then any built tx would fail in it's check tx phase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we not just do the length check in these function calls (TM address length)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should return an error for invalid addresses here, rather than returning an invalid AccAddress{}.
For simplicity we should use a single global constant tmhash.TruncatedSize (definitely not 32 bytes, but 20).
And if the length is invalid, this function should return an error immediately.