generated from AArnott/Library.Template
-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Give TEX addresses their own receiver struct
Even though `TransparentP2PKHReceiver` is perfectly serviceable for TEX addresses, reusing the type is inviting bugs where the app or library may misinterpret a TEX address as an ordinary transparent address and neglect the special treatment that TEX addresses require.
- Loading branch information
Showing
8 changed files
with
155 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
// Copyright (c) Andrew Arnott. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
namespace Nerdbank.Zcash; | ||
|
||
/// <summary> | ||
/// A receiver that contains the cryptography parameters required to send Zcash to the <see cref="Pool.Transparent"/> pool | ||
/// by way of a Pay to Public Key Hash method. | ||
/// </summary> | ||
/// <remarks> | ||
/// This receiver is used for <see cref="TexAddress"/> to represent receivers that must only be sent transparent funds. | ||
/// It is otherwise equivalent to <see cref="TransparentP2PKHReceiver"/>. | ||
/// </remarks> | ||
public unsafe struct TexReceiver : IPoolReceiver, IEquatable<TexReceiver> | ||
{ | ||
private readonly TransparentP2PKHReceiver p2pkhReceiver; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="TexReceiver"/> struct. | ||
/// </summary> | ||
/// <param name="p2pkh">The validating key hash.</param> | ||
/// <exception cref="ArgumentException">Thrown when the arguments have an unexpected length.</exception> | ||
public TexReceiver(ReadOnlySpan<byte> p2pkh) | ||
{ | ||
this.p2pkhReceiver = new(p2pkh); | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="TexReceiver"/> struct. | ||
/// </summary> | ||
/// <param name="publicKey">The EC public key to create a receiver for.</param> | ||
public TexReceiver(Zip32HDWallet.Transparent.ExtendedViewingKey publicKey) | ||
{ | ||
this.p2pkhReceiver = new(publicKey); | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="TexReceiver"/> struct. | ||
/// </summary> | ||
/// <param name="publicKey">The EC public key to create a receiver for.</param> | ||
public TexReceiver(Transparent.PublicKey publicKey) | ||
{ | ||
this.p2pkhReceiver = new(publicKey); | ||
} | ||
|
||
/// <inheritdoc/> | ||
public readonly Pool Pool => Pool.Transparent; | ||
|
||
/// <summary> | ||
/// Gets the encoded representation of the entire receiver. | ||
/// </summary> | ||
[UnscopedRef] | ||
public readonly ReadOnlySpan<byte> Span => this.ValidatingKeyHash; | ||
|
||
/// <inheritdoc /> | ||
public readonly int EncodingLength => this.Span.Length; | ||
|
||
/// <summary> | ||
/// Gets the validating key hash. | ||
/// </summary> | ||
[UnscopedRef] | ||
public readonly ReadOnlySpan<byte> ValidatingKeyHash => this.p2pkhReceiver.ValidatingKeyHash; | ||
|
||
/// <summary> | ||
/// Converts a <see cref="TransparentP2PKHReceiver"/> into a <see cref="TexReceiver" />. | ||
/// </summary> | ||
/// <param name="receiver">The receiver to convert from.</param> | ||
public static implicit operator TexReceiver(in TransparentP2PKHReceiver receiver) => new(receiver.ValidatingKeyHash); | ||
|
||
/// <summary> | ||
/// Converts a <see cref="TexReceiver"/> into a <see cref="TransparentP2PKHReceiver" />. | ||
/// </summary> | ||
/// <param name="receiver">The receiver to convert from.</param> | ||
public static explicit operator TransparentP2PKHReceiver(in TexReceiver receiver) => new(receiver.ValidatingKeyHash); | ||
|
||
/// <inheritdoc/> | ||
public int Encode(Span<byte> buffer) => this.Span.CopyToRetLength(buffer); | ||
|
||
/// <inheritdoc/> | ||
public bool Equals(TexReceiver other) => this.ValidatingKeyHash.SequenceEqual(other.ValidatingKeyHash); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// Copyright (c) Andrew Arnott. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
public class TexReceiverTests | ||
{ | ||
[Fact] | ||
public void Ctor() | ||
{ | ||
byte[] hash = new byte[20]; | ||
hash[1] = 2; | ||
TexReceiver receiver = new(hash); | ||
Assert.Equal(hash, receiver.ValidatingKeyHash.ToArray()); | ||
|
||
// Verify that a copy of the data has been made. | ||
hash[0] = 3; | ||
Assert.Equal(0, receiver.ValidatingKeyHash[0]); | ||
} | ||
|
||
[Fact] | ||
public void Ctor_ArgValidation() | ||
{ | ||
Assert.Throws<ArgumentException>(() => new TexReceiver(new byte[1])); | ||
} | ||
|
||
[Fact] | ||
public void Pool_Transparent() => Assert.Equal(Pool.Transparent, default(TexReceiver).Pool); | ||
|
||
[Fact] | ||
public void TexToTransparentConversion() | ||
{ | ||
Span<byte> p2pkh = stackalloc byte[20]; | ||
Random.Shared.NextBytes(p2pkh); | ||
TexReceiver texReceiver = new(p2pkh); | ||
TransparentP2PKHReceiver transparentReceiver = (TransparentP2PKHReceiver)texReceiver; | ||
Assert.Equal(texReceiver.ValidatingKeyHash, transparentReceiver.ValidatingKeyHash); | ||
} | ||
|
||
[Fact] | ||
public void TransparentToTexConversion() | ||
{ | ||
Span<byte> p2pkh = stackalloc byte[20]; | ||
Random.Shared.NextBytes(p2pkh); | ||
TransparentP2PKHReceiver transparentReceiver = new(p2pkh); | ||
TexReceiver texReceiver = transparentReceiver; | ||
Assert.Equal(transparentReceiver.ValidatingKeyHash, texReceiver.ValidatingKeyHash); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters