Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions consensus/merkle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ func TestElementAccumulatorEncoding(t *testing.T) {
exp string
}{
{0, `{"numLeaves":0,"trees":[]}`},
{1, `{"numLeaves":1,"trees":["h:0000000000000000000000000000000000000000000000000000000000000000"]}`},
{2, `{"numLeaves":2,"trees":["h:0100000000000000000000000000000000000000000000000000000000000000"]}`},
{3, `{"numLeaves":3,"trees":["h:0000000000000000000000000000000000000000000000000000000000000000","h:0100000000000000000000000000000000000000000000000000000000000000"]}`},
{10, `{"numLeaves":10,"trees":["h:0100000000000000000000000000000000000000000000000000000000000000","h:0300000000000000000000000000000000000000000000000000000000000000"]}`},
{1 << 16, `{"numLeaves":65536,"trees":["h:1000000000000000000000000000000000000000000000000000000000000000"]}`},
{1 << 32, `{"numLeaves":4294967296,"trees":["h:2000000000000000000000000000000000000000000000000000000000000000"]}`},
{1, `{"numLeaves":1,"trees":["0000000000000000000000000000000000000000000000000000000000000000"]}`},
{2, `{"numLeaves":2,"trees":["0100000000000000000000000000000000000000000000000000000000000000"]}`},
{3, `{"numLeaves":3,"trees":["0000000000000000000000000000000000000000000000000000000000000000","0100000000000000000000000000000000000000000000000000000000000000"]}`},
{10, `{"numLeaves":10,"trees":["0100000000000000000000000000000000000000000000000000000000000000","0300000000000000000000000000000000000000000000000000000000000000"]}`},
{1 << 16, `{"numLeaves":65536,"trees":["1000000000000000000000000000000000000000000000000000000000000000"]}`},
{1 << 32, `{"numLeaves":4294967296,"trees":["2000000000000000000000000000000000000000000000000000000000000000"]}`},
} {
acc := ElementAccumulator{NumLeaves: test.numLeaves}
for i := range acc.Trees {
Expand Down
14 changes: 7 additions & 7 deletions rhp/v2/merkle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,16 @@ func recNodeRoot(roots []types.Hash256) types.Hash256 {
func TestSectorRoot(t *testing.T) {
// test some known roots
var sector [SectorSize]byte
if SectorRoot(&sector).String() != "h:50ed59cecd5ed3ca9e65cec0797202091dbba45272dafa3faa4e27064eedd52c" {
if SectorRoot(&sector).String() != "50ed59cecd5ed3ca9e65cec0797202091dbba45272dafa3faa4e27064eedd52c" {
t.Error("wrong Merkle root for empty sector")
}
sector[0] = 1
if SectorRoot(&sector).String() != "h:8c20a2c90a733a5139cc57e45755322e304451c3434b0c0a0aad87f2f89a44ab" {
if SectorRoot(&sector).String() != "8c20a2c90a733a5139cc57e45755322e304451c3434b0c0a0aad87f2f89a44ab" {
t.Error("wrong Merkle root for sector[0] = 1")
}
sector[0] = 0
sector[SectorSize-1] = 1
if SectorRoot(&sector).String() != "h:d0ab6691d76750618452e920386e5f6f98fdd1219a70a06f06ef622ac6c6373c" {
if SectorRoot(&sector).String() != "d0ab6691d76750618452e920386e5f6f98fdd1219a70a06f06ef622ac6c6373c" {
t.Error("wrong Merkle root for sector[SectorSize-1] = 1")
}

Expand Down Expand Up @@ -95,11 +95,11 @@ func TestMetaRoot(t *testing.T) {
t.Error("wrong Merkle root for single root")
}
roots = make([]types.Hash256, 32)
if MetaRoot(roots).String() != "h:1c23727030051d1bba1c887273addac2054afbd6926daddef6740f4f8bf1fb7f" {
if MetaRoot(roots).String() != "1c23727030051d1bba1c887273addac2054afbd6926daddef6740f4f8bf1fb7f" {
t.Error("wrong Merkle root for 32 empty roots")
}
roots[0][0] = 1
if MetaRoot(roots).String() != "h:c5da05749139505704ea18a5d92d46427f652ac79c5f5712e4aefb68e20dffb8" {
if MetaRoot(roots).String() != "c5da05749139505704ea18a5d92d46427f652ac79c5f5712e4aefb68e20dffb8" {
t.Error("wrong Merkle root for roots[0][0] = 1")
}

Expand Down Expand Up @@ -161,7 +161,7 @@ func TestProofAccumulator(t *testing.T) {
for _, root := range roots {
pa.insertNode(root, 0)
}
if pa.root().String() != "h:1c23727030051d1bba1c887273addac2054afbd6926daddef6740f4f8bf1fb7f" {
if pa.root().String() != "1c23727030051d1bba1c887273addac2054afbd6926daddef6740f4f8bf1fb7f" {
t.Error("wrong root for 32 empty roots")
}

Expand All @@ -170,7 +170,7 @@ func TestProofAccumulator(t *testing.T) {
for _, root := range roots {
pa.insertNode(root, 0)
}
if pa.root().String() != "h:c5da05749139505704ea18a5d92d46427f652ac79c5f5712e4aefb68e20dffb8" {
if pa.root().String() != "c5da05749139505704ea18a5d92d46427f652ac79c5f5712e4aefb68e20dffb8" {
t.Error("wrong root for roots[0][0] = 1")
}

Expand Down
3 changes: 1 addition & 2 deletions rhp/v2/rhp.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"errors"
"fmt"
"net"
"strings"
"time"

"go.sia.tech/core/types"
Expand Down Expand Up @@ -91,7 +90,7 @@ func (hs HostSettings) MarshalJSON() ([]byte, error) {
"remainingstorage": hs.RemainingStorage,
"sectorsize": hs.SectorSize,
"totalstorage": hs.TotalStorage,
"unlockhash": strings.TrimPrefix(hs.Address.String(), "addr:"), // trim the "addr:" prefix for compatibility with siad
"unlockhash": hs.Address.String(),
"windowsize": hs.WindowSize,
"collateral": hs.Collateral,
"maxcollateral": hs.MaxCollateral,
Expand Down
6 changes: 3 additions & 3 deletions rhp/v4/merkle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,16 @@ func recNodeRoot(roots []types.Hash256) types.Hash256 {
func TestSectorRoot(t *testing.T) {
// test some known roots
var sector [SectorSize]byte
if SectorRoot(&sector).String() != "h:50ed59cecd5ed3ca9e65cec0797202091dbba45272dafa3faa4e27064eedd52c" {
if SectorRoot(&sector).String() != "50ed59cecd5ed3ca9e65cec0797202091dbba45272dafa3faa4e27064eedd52c" {
t.Error("wrong Merkle root for empty sector")
}
sector[0] = 1
if SectorRoot(&sector).String() != "h:8c20a2c90a733a5139cc57e45755322e304451c3434b0c0a0aad87f2f89a44ab" {
if SectorRoot(&sector).String() != "8c20a2c90a733a5139cc57e45755322e304451c3434b0c0a0aad87f2f89a44ab" {
t.Error("wrong Merkle root for sector[0] = 1")
}
sector[0] = 0
sector[SectorSize-1] = 1
if SectorRoot(&sector).String() != "h:d0ab6691d76750618452e920386e5f6f98fdd1219a70a06f06ef622ac6c6373c" {
if SectorRoot(&sector).String() != "d0ab6691d76750618452e920386e5f6f98fdd1219a70a06f06ef622ac6c6373c" {
t.Error("wrong Merkle root for sector[SectorSize-1] = 1")
}

Expand Down
12 changes: 6 additions & 6 deletions types/policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ func TestPolicyVerify(t *testing.T) {
func TestPolicyGolden(t *testing.T) {
pk := PublicKey{1, 2, 3}
p := SpendPolicy{PolicyTypeUnlockConditions(StandardUnlockConditions(pk))}
if p.Address().String() != "addr:72b0762b382d4c251af5ae25b6777d908726d75962e5224f98d7f619bb39515dd64b9a56043a" {
if p.Address().String() != "72b0762b382d4c251af5ae25b6777d908726d75962e5224f98d7f619bb39515dd64b9a56043a" {
t.Fatal("wrong address:", p, p.Address())
} else if StandardUnlockHash(pk) != p.Address() {
t.Fatal("StandardUnlockHash differs from Policy.Address")
Expand All @@ -289,7 +289,7 @@ func TestPolicyGolden(t *testing.T) {
PolicyPublicKey(PublicKey{4, 5, 6}),
}),
})
if p.Address().String() != "addr:111d2995afa8bf162180a647b9f1eb6a275fe8818e836b69b351871d5caf9c590ed25aec0616" {
if p.Address().String() != "111d2995afa8bf162180a647b9f1eb6a275fe8818e836b69b351871d5caf9c590ed25aec0616" {
t.Fatal("wrong address:", p, p.Address())
}
}
Expand Down Expand Up @@ -395,7 +395,7 @@ func TestSpendPolicyMarshalJSON(t *testing.T) {
},
{
sp: PolicyHash(hash),
exp: fmt.Sprintf(`{"type":"h","policy":"h:%x"}`, hash[:]),
exp: fmt.Sprintf(`{"type":"h","policy":"%x"}`, hash[:]),
},
{
sp: PolicyThreshold(2, []SpendPolicy{
Expand Down Expand Up @@ -453,13 +453,13 @@ func TestSatisfiedPolicyMarshalJSON(t *testing.T) {
sp: PolicyThreshold(1, []SpendPolicy{PolicyPublicKey(publicKey), PolicyHash(hash)}),
signatures: []Signature{signature},
preimages: [][32]byte{{1, 2, 3}},
exp: fmt.Sprintf(`{"policy":{"type":"thresh","policy":{"n":1,"of":[{"type":"pk","policy":"ed25519:%x"},{"type":"h","policy":"h:%x"}]}},"signatures":[%q],"preimages":["0102030000000000000000000000000000000000000000000000000000000000"]}`, publicKey[:], hash[:], signature),
exp: fmt.Sprintf(`{"policy":{"type":"thresh","policy":{"n":1,"of":[{"type":"pk","policy":"ed25519:%x"},{"type":"h","policy":"%x"}]}},"signatures":[%q],"preimages":["0102030000000000000000000000000000000000000000000000000000000000"]}`, publicKey[:], hash[:], signature),
},
{
name: "PolicyWithPreimagesOnly",
sp: PolicyHash(hash),
preimages: [][32]byte{{4, 5, 6}},
exp: fmt.Sprintf(`{"policy":{"type":"h","policy":"h:%x"},"preimages":["0405060000000000000000000000000000000000000000000000000000000000"]}`, hash[:]),
exp: fmt.Sprintf(`{"policy":{"type":"h","policy":"%x"},"preimages":["0405060000000000000000000000000000000000000000000000000000000000"]}`, hash[:]),
},
{
name: "PolicyWithEmptySignatures",
Expand All @@ -469,7 +469,7 @@ func TestSatisfiedPolicyMarshalJSON(t *testing.T) {
{
name: "PolicyWithEmptyPreimages",
sp: PolicyHash(hash),
exp: fmt.Sprintf(`{"policy":{"type":"h","policy":"h:%x"}}`, hash[:]),
exp: fmt.Sprintf(`{"policy":{"type":"h","policy":"%x"}}`, hash[:]),
},
}

Expand Down
100 changes: 54 additions & 46 deletions types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -830,39 +830,28 @@ func (b *Block) ID() BlockID {
return BlockID(HashBytes(buf))
}

// Implementations of fmt.Stringer, encoding.Text(Un)marshaler, and json.(Un)marshaler

func stringerHex(prefix string, data []byte) string {
return prefix + ":" + hex.EncodeToString(data)
}

func marshalHex(prefix string, data []byte) ([]byte, error) {
return []byte(stringerHex(prefix, data)), nil
}

func unmarshalHex(dst []byte, prefix string, data []byte) error {
data = bytes.TrimPrefix(data, []byte(prefix+":"))
func unmarshalHex(dst []byte, data []byte) error {
if len(data) > len(dst)*2 {
return fmt.Errorf("decoding %v:<hex> failed: input too long", prefix)
return errors.New("input too long")
}
n, err := hex.Decode(dst, data)
if err == nil && n < len(dst) {
err = io.ErrUnexpectedEOF
}
if err != nil {
return fmt.Errorf("decoding %v:<hex> failed: %w", prefix, err)
return fmt.Errorf("decoding %q failed: %w", data, err)
}
return nil
}

// String implements fmt.Stringer.
func (h Hash256) String() string { return stringerHex("h", h[:]) }
func (h Hash256) String() string { return hex.EncodeToString(h[:]) }

// MarshalText implements encoding.TextMarshaler.
func (h Hash256) MarshalText() ([]byte, error) { return marshalHex("h", h[:]) }
func (h Hash256) MarshalText() ([]byte, error) { return []byte(hex.EncodeToString(h[:])), nil }

// UnmarshalText implements encoding.TextUnmarshaler.
func (h *Hash256) UnmarshalText(b []byte) error { return unmarshalHex(h[:], "h", b) }
func (h *Hash256) UnmarshalText(b []byte) error { return unmarshalHex(h[:], b) }

// String implements fmt.Stringer.
func (ci ChainIndex) String() string {
Expand Down Expand Up @@ -941,7 +930,7 @@ func (s *Specifier) UnmarshalText(b []byte) error {

// MarshalText implements encoding.TextMarshaler.
func (uk UnlockKey) MarshalText() ([]byte, error) {
return marshalHex(uk.Algorithm.String(), uk.Key)
return []byte(uk.Algorithm.String() + ":" + hex.EncodeToString(uk.Key)), nil
}

// UnmarshalText implements encoding.TextUnmarshaler.
Expand All @@ -959,25 +948,28 @@ func (uk *UnlockKey) UnmarshalText(b []byte) error {
// String implements fmt.Stringer.
func (a Address) String() string {
checksum := HashBytes(a[:])
return stringerHex("addr", append(a[:], checksum[:6]...))
return hex.EncodeToString(append(a[:], checksum[:6]...))
}

// MarshalText implements encoding.TextMarshaler.
func (a Address) MarshalText() ([]byte, error) { return []byte(a.String()), nil }

// UnmarshalText implements encoding.TextUnmarshaler.
func (a *Address) UnmarshalText(b []byte) (err error) {
func (a *Address) UnmarshalText(b []byte) error {
withChecksum := make([]byte, 32+6)
n, err := hex.Decode(withChecksum, bytes.TrimPrefix(b, []byte("addr:")))
if len(b) != len(withChecksum)*2 {
return fmt.Errorf("address must be %d characters", len(withChecksum)*2)
}
n, err := hex.Decode(withChecksum, b)
if err != nil {
err = fmt.Errorf("decoding addr:<hex> failed: %w", err)
return fmt.Errorf("decoding %q failed: %w", b, err)
} else if n != len(withChecksum) {
err = fmt.Errorf("decoding addr:<hex> failed: %w", io.ErrUnexpectedEOF)
return fmt.Errorf("decoding %q failed: %w", b, io.ErrUnexpectedEOF)
} else if checksum := HashBytes(withChecksum[:32]); !bytes.Equal(checksum[:6], withChecksum[32:]) {
err = errors.New("bad checksum")
return errors.New("bad checksum")
}
copy(a[:], withChecksum[:32])
return
return nil
}

// ParseAddress parses an address from a prefixed hex encoded string.
Expand All @@ -987,71 +979,87 @@ func ParseAddress(s string) (a Address, err error) {
}

// String implements fmt.Stringer.
func (bid BlockID) String() string { return stringerHex("bid", bid[:]) }
func (bid BlockID) String() string { return hex.EncodeToString(bid[:]) }

// MarshalText implements encoding.TextMarshaler.
func (bid BlockID) MarshalText() ([]byte, error) { return marshalHex("bid", bid[:]) }
func (bid BlockID) MarshalText() ([]byte, error) { return []byte(hex.EncodeToString(bid[:])), nil }

// UnmarshalText implements encoding.TextUnmarshaler.
func (bid *BlockID) UnmarshalText(b []byte) error { return unmarshalHex(bid[:], "bid", b) }
func (bid *BlockID) UnmarshalText(b []byte) error { return unmarshalHex(bid[:], b) }

// String implements fmt.Stringer.
func (pk PublicKey) String() string { return stringerHex("ed25519", pk[:]) }
func (pk PublicKey) String() string { return "ed25519:" + hex.EncodeToString(pk[:]) }

// MarshalText implements encoding.TextMarshaler.
func (pk PublicKey) MarshalText() ([]byte, error) { return marshalHex("ed25519", pk[:]) }
func (pk PublicKey) MarshalText() ([]byte, error) { return []byte(pk.String()), nil }

// UnmarshalText implements encoding.TextUnmarshaler.
func (pk *PublicKey) UnmarshalText(b []byte) error { return unmarshalHex(pk[:], "ed25519", b) }
func (pk *PublicKey) UnmarshalText(b []byte) error {
i := bytes.IndexByte(b, ':')
if i < 0 {
return errors.New("missing separator")
} else if string(b[:i]) != "ed25519" {
return fmt.Errorf("unknown algorithm %q", b[:i])
}
return unmarshalHex(pk[:], b[i+1:])
}

// String implements fmt.Stringer.
func (tid TransactionID) String() string { return stringerHex("txid", tid[:]) }
func (tid TransactionID) String() string { return hex.EncodeToString(tid[:]) }

// MarshalText implements encoding.TextMarshaler.
func (tid TransactionID) MarshalText() ([]byte, error) { return marshalHex("txid", tid[:]) }
func (tid TransactionID) MarshalText() ([]byte, error) {
return []byte(hex.EncodeToString(tid[:])), nil
}

// UnmarshalText implements encoding.TextUnmarshaler.
func (tid *TransactionID) UnmarshalText(b []byte) error { return unmarshalHex(tid[:], "txid", b) }
func (tid *TransactionID) UnmarshalText(b []byte) error { return unmarshalHex(tid[:], b) }

// String implements fmt.Stringer.
func (scoid SiacoinOutputID) String() string { return stringerHex("scoid", scoid[:]) }
func (scoid SiacoinOutputID) String() string { return hex.EncodeToString(scoid[:]) }

// MarshalText implements encoding.TextMarshaler.
func (scoid SiacoinOutputID) MarshalText() ([]byte, error) { return marshalHex("scoid", scoid[:]) }
func (scoid SiacoinOutputID) MarshalText() ([]byte, error) {
return []byte(hex.EncodeToString(scoid[:])), nil
}

// UnmarshalText implements encoding.TextUnmarshaler.
func (scoid *SiacoinOutputID) UnmarshalText(b []byte) error {
return unmarshalHex(scoid[:], "scoid", b)
return unmarshalHex(scoid[:], b)
}

// String implements fmt.Stringer.
func (sfoid SiafundOutputID) String() string { return stringerHex("sfoid", sfoid[:]) }
func (sfoid SiafundOutputID) String() string { return hex.EncodeToString(sfoid[:]) }

// MarshalText implements encoding.TextMarshaler.
func (sfoid SiafundOutputID) MarshalText() ([]byte, error) { return marshalHex("sfoid", sfoid[:]) }
func (sfoid SiafundOutputID) MarshalText() ([]byte, error) {
return []byte(hex.EncodeToString(sfoid[:])), nil
}

// UnmarshalText implements encoding.TextUnmarshaler.
func (sfoid *SiafundOutputID) UnmarshalText(b []byte) error {
return unmarshalHex(sfoid[:], "sfoid", b)
return unmarshalHex(sfoid[:], b)
}

// String implements fmt.Stringer.
func (fcid FileContractID) String() string { return stringerHex("fcid", fcid[:]) }
func (fcid FileContractID) String() string { return hex.EncodeToString(fcid[:]) }

// MarshalText implements encoding.TextMarshaler.
func (fcid FileContractID) MarshalText() ([]byte, error) { return marshalHex("fcid", fcid[:]) }
func (fcid FileContractID) MarshalText() ([]byte, error) {
return []byte(hex.EncodeToString(fcid[:])), nil
}

// UnmarshalText implements encoding.TextUnmarshaler.
func (fcid *FileContractID) UnmarshalText(b []byte) error { return unmarshalHex(fcid[:], "fcid", b) }
func (fcid *FileContractID) UnmarshalText(b []byte) error { return unmarshalHex(fcid[:], b) }

// String implements fmt.Stringer.
func (sig Signature) String() string { return stringerHex("sig", sig[:]) }
func (sig Signature) String() string { return hex.EncodeToString(sig[:]) }

// MarshalText implements encoding.TextMarshaler.
func (sig Signature) MarshalText() ([]byte, error) { return marshalHex("sig", sig[:]) }
func (sig Signature) MarshalText() ([]byte, error) { return []byte(hex.EncodeToString(sig[:])), nil }

// UnmarshalText implements encoding.TextUnmarshaler.
func (sig *Signature) UnmarshalText(b []byte) error { return unmarshalHex(sig[:], "sig", b) }
func (sig *Signature) UnmarshalText(b []byte) error { return unmarshalHex(sig[:], b) }

// MarshalJSON implements json.Marshaler.
func (fcr FileContractRevision) MarshalJSON() ([]byte, error) {
Expand Down
22 changes: 11 additions & 11 deletions types/currency_test.go → types/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -761,27 +761,27 @@ func TestParseCurrency(t *testing.T) {

func TestUnmarshalHex(t *testing.T) {
for _, test := range []struct {
prefix string
data string
dstLen int
err string
}{
{"", strings.Repeat("0", 2), 1, ""},
{"", strings.Repeat("_", 2), 1, "decoding :<hex> failed: encoding/hex: invalid byte: U+005F '_'"},
{"ed25519", strings.Repeat("0", 62), 32, "decoding ed25519:<hex> failed: unexpected EOF"},
{"ed25519", strings.Repeat("0", 63), 32, "decoding ed25519:<hex> failed: encoding/hex: odd length hex string"},
{"ed25519", strings.Repeat("0", 64), 32, ""},
{"ed25519", strings.Repeat("0", 65), 32, "decoding ed25519:<hex> failed: input too long"},
{strings.Repeat("_", 2), 1, "encoding/hex: invalid byte: U+005F '_'"},
{strings.Repeat("0", 62), 32, "unexpected EOF"},
{strings.Repeat("0", 63), 32, "encoding/hex: odd length hex string"},
{strings.Repeat("0", 65), 32, "input too long"},

{strings.Repeat("0", 2), 1, ""},
{strings.Repeat("0", 64), 32, ""},
} {
dst := make([]byte, test.dstLen)
err := unmarshalHex(dst, test.prefix, []byte(test.data))
err := unmarshalHex(dst, []byte(test.data))
if err == nil {
if test.err != "" {
t.Errorf("unmarshalHex(%s, %s) expected error %q, got nil", test.prefix, test.data, test.err)
t.Errorf("unmarshal %q expected error %q, got nil", test.data, test.err)
}
} else {
if err.Error() != test.err {
t.Errorf("unmarshalHex(%s, %s) expected error %q, got %q", test.prefix, test.data, test.err, err)
if !strings.Contains(err.Error(), test.err) {
t.Errorf("unmarshal %q expected error %q, got %q", test.data, test.err, err)
}
}
}
Expand Down