Skip to content
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

Change penalty from fixed to relative time lock op_csv instead of op_clt #13

Merged
merged 9 commits into from
Nov 20, 2023
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
using System.Linq.Expressions;
using System.Text;
using Angor.Shared;
using Angor.Shared.Models;
using Blockcore.NBitcoin;
using NBitcoin;
using NBitcoin.Crypto;
using Script = Blockcore.Consensus.ScriptInfo.Script;


namespace Angor.Shared.Protocol
namespace Angor.Test.DataBuilders
{
public class AngorScripts
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
using Angor.Shared;
using System.Text;
using Angor.Shared;
using Angor.Shared.Models;
using Angor.Shared.Protocol;
using Blockcore.NBitcoin.DataEncoders;
using NBitcoin;
using NBitcoin.Policy;
using System.Text;
using BitcoinAddress = Blockcore.NBitcoin.BitcoinAddress;
using FeeRate = Blockcore.NBitcoin.FeeRate;
using IndexedTxOut = NBitcoin.IndexedTxOut;
Expand All @@ -21,6 +20,8 @@
using Utils = NBitcoin.Utils;
using WitScript = NBitcoin.WitScript;

namespace Angor.Test.DataBuilders;

public class InvestmentOperations
{
private readonly IWalletOperations _walletOperations;
Expand Down Expand Up @@ -246,7 +247,7 @@ public List<Transaction> BuildRecoverInvestorFundsTransactions(InvestorContext c

var spendingScript = ScriptBuilder.GetInvestorPenaltyTransactionScript(
investorReceiveAddress,
context.ProjectInfo.PenaltyDate);
context.ProjectInfo.PenaltyDays);

stageTransaction.Outputs.Add(new NBitcoin.TxOut(_.TxOut.Value,
new NBitcoin.Script(spendingScript.WitHash.ScriptPubKey.ToBytes())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using Blockcore.NBitcoin;
using Blockcore.Networks;

namespace Angor.Shared.Protocol;
namespace Angor.Test.DataBuilders;

public class ProjectOperations
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
using Angor.Shared;
using Angor.Shared.Models;
using Blockcore.Consensus.ScriptInfo;
using Blockcore.NBitcoin;
using Blockcore.NBitcoin.Crypto;
using System.Collections.Generic;
using Angor.Shared.Models;

namespace Angor.Shared;
namespace Angor.Test.DataBuilders;

public class ScriptBuilder
{
Expand Down Expand Up @@ -55,16 +54,19 @@ public static (PubKey investorKey, uint256? secretHash) GetInvestmentDataFromOpR
return (pubKey, secretHash);
}

public static Script GetInvestorPenaltyTransactionScript(string investorKey, DateTime punishmentLockTime)
public static Script GetInvestorPenaltyTransactionScript(string investorKey, int punishmentLockDays)
{
var unixTime = Utils.DateTimeToUnixTime(punishmentLockTime);

//var unixTime = Utils.DateTimeToUnixTime(punishmentLockTime);

//var totalSeconds = (uint)TimeSpan.FromDays(punishmentLockDays).TotalSeconds;
var sequence = new Sequence(TimeSpan.FromDays(punishmentLockDays));

return new(new List<Op>
{
Op.GetPushOp(new NBitcoin.PubKey(investorKey).ToBytes()),
OpcodeType.OP_CHECKSIGVERIFY,
Op.GetPushOp(unixTime),
OpcodeType.OP_CHECKLOCKTIMEVERIFY
Op.GetPushOp((uint)sequence),
OpcodeType.OP_CHECKSEQUENCEVERIFY
});
}

Expand Down
1 change: 0 additions & 1 deletion src/Angor.Test/DerivationOperationsTest.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Angor.Shared;
using Angor.Shared.Models;
using Angor.Shared.Networks;
using Angor.Shared.Protocol;
using Blockcore.Consensus.ScriptInfo;
using Blockcore.NBitcoin;
using Blockcore.NBitcoin.BIP32;
Expand Down
7 changes: 4 additions & 3 deletions src/Angor.Test/InvestmentOperationsTest.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Angor.Shared;
using Angor.Shared.Models;
using Angor.Shared.Networks;
using Angor.Test.DataBuilders;
using Blockcore.NBitcoin;
using Blockcore.NBitcoin.Crypto;
using Blockcore.NBitcoin.DataEncoders;
Expand Down Expand Up @@ -419,7 +420,7 @@ public void SpendInvestorRecoveryTest()
FounderKey = funderKey,
FounderRecoveryKey = funderRecoveryKey,
ProjectIdentifier = angorKey,
PenaltyDate = DateTime.UtcNow.AddDays(5),
PenaltyDays = 5,
ProjectSeeders = new ProjectSeeders()
},
InvestorKey = Encoders.Hex.EncodeData(investorKey.PubKey.ToBytes()),
Expand Down Expand Up @@ -519,7 +520,7 @@ public void SpendInvestorConsolidatedRecoveryTest()
FounderKey = funderKey,
FounderRecoveryKey = funderRecoveryKey,
ProjectIdentifier = angorKey,
PenaltyDate = DateTime.UtcNow.AddDays(5),
PenaltyDays = 5,
ProjectSeeders = new ProjectSeeders
{
Threshold = 2,
Expand Down Expand Up @@ -632,7 +633,7 @@ public void SpendSeederConsolidatedRecoveryTest()
FounderKey = funderKey,
FounderRecoveryKey = funderRecoveryKey,
ProjectIdentifier = angorKey,
PenaltyDate = DateTime.UtcNow.AddDays(5),
PenaltyDays = 5,
ProjectSeeders = new ProjectSeeders()
},
InvestorKey = Encoders.Hex.EncodeData(seederKey.PubKey.ToBytes()),
Expand Down
2 changes: 1 addition & 1 deletion src/Angor.Test/ProtocolNew/AngorTestData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ protected ProjectInfo GivenValidProjectInvestmentInfo( WalletWords? words = null
projectInvestmentInfo.TargetAmount = 3;
projectInvestmentInfo.StartDate = startDate.Value;
projectInvestmentInfo.ExpiryDate = startDate.Value.AddDays(5);
projectInvestmentInfo.PenaltyDate = startDate.Value.AddDays(10);
projectInvestmentInfo.PenaltyDays = 10;
projectInvestmentInfo.Stages = new List<Stage>
{
new() { AmountToRelease = (decimal)0.1, ReleaseDate = startDate.Value.AddDays(1) },
Expand Down
1 change: 1 addition & 0 deletions src/Angor.Test/ProtocolNew/FounderTransactionActionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Angor.Shared.ProtocolNew;
using Angor.Shared.ProtocolNew.Scripts;
using Angor.Shared.ProtocolNew.TransactionBuilders;
using Angor.Test.DataBuilders;
using Blockcore.NBitcoin;
using Blockcore.NBitcoin.DataEncoders;
using Microsoft.Extensions.Logging.Abstractions;
Expand Down
15 changes: 8 additions & 7 deletions src/Angor.Test/ProtocolNew/InvestmentIntegrationsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Angor.Shared.ProtocolNew;
using Angor.Shared.ProtocolNew.Scripts;
using Angor.Shared.ProtocolNew.TransactionBuilders;
using Angor.Test.DataBuilders;
using Blockcore.Consensus.ScriptInfo;
using Blockcore.Consensus.TransactionInfo;
using Blockcore.NBitcoin;
Expand Down Expand Up @@ -79,7 +80,7 @@ public InvestmentIntegrationsTests()
new ProjectScriptsBuilder(_derivationOperations),
new InvestmentScriptBuilder(new SeederScriptTreeBuilder())),
new InvestmentTransactionBuilder(_networkConfiguration.Object,
new ProjectScriptsBuilder(_derivationOperations), new InvestmentScriptBuilder(new SeederScriptTreeBuilder())),
new ProjectScriptsBuilder(_derivationOperations), new InvestmentScriptBuilder(new SeederScriptTreeBuilder()), new TaprootScriptBuilder()),
new TaprootScriptBuilder(), _networkConfiguration.Object);

_investorTransactionActions = new InvestorTransactionActions(new NullLogger<InvestorTransactionActions>(),
Expand All @@ -90,7 +91,7 @@ public InvestmentIntegrationsTests()
new InvestmentScriptBuilder(new SeederScriptTreeBuilder())),
new InvestmentTransactionBuilder(_networkConfiguration.Object,
new ProjectScriptsBuilder(_derivationOperations),
new InvestmentScriptBuilder(new SeederScriptTreeBuilder())),
new InvestmentScriptBuilder(new SeederScriptTreeBuilder()), new TaprootScriptBuilder()),
new TaprootScriptBuilder(), _networkConfiguration.Object);

_founderTransactionActions = new FounderTransactionActions(new NullLogger<FounderTransactionActions>(), _networkConfiguration.Object,
Expand Down Expand Up @@ -258,8 +259,8 @@ public void SeederTransaction_EndOfProject_Test()
projectInvestmentInfo.FounderRecoveryKey = _derivationOperations.DeriveFounderRecoveryKey(words, 1);
projectInvestmentInfo.ProjectIdentifier =
_derivationOperations.DeriveAngorKey(projectInvestmentInfo.FounderKey, angorRootKey);
projectInvestmentInfo.PenaltyDate = DateTime.Now.AddMonths(6);

projectInvestmentInfo.PenaltyDays = 180;

// Create the seeder 1 params
var seeder11Key = new Key();
Expand Down Expand Up @@ -433,7 +434,7 @@ public void SpendSeederRecoveryTest()
FounderKey = funderKey,
FounderRecoveryKey = founderRecoveryKey,
ProjectIdentifier = angorKey,
PenaltyDate = DateTime.UtcNow.AddDays(5),
PenaltyDays = 5,
ProjectSeeders = new ProjectSeeders()
},
InvestorKey = Encoders.Hex.EncodeData(seederKey.PubKey.ToBytes()),
Expand All @@ -449,7 +450,7 @@ public void SpendSeederRecoveryTest()

var recoveryTransaction = _seederTransactionActions.BuildRecoverSeederFundsTransaction(investorContext.ProjectInfo,
investmentTransaction,
investorContext.ProjectInfo.PenaltyDate, Encoders.Hex.EncodeData(seederFundsRecoveryKey.PubKey.ToBytes()));
investorContext.ProjectInfo.PenaltyDays, Encoders.Hex.EncodeData(seederFundsRecoveryKey.PubKey.ToBytes()));

var founderSignatures = _founderTransactionActions.SignInvestorRecoveryTransactions(investorContext.ProjectInfo,
investmentTransaction.ToHex(),recoveryTransaction,
Expand Down Expand Up @@ -493,7 +494,7 @@ public void SpendInvestorRecoveryTest()
TargetAmount = 3,
StartDate = DateTime.UtcNow,
ExpiryDate = DateTime.UtcNow.AddDays(5),
PenaltyDate = DateTime.UtcNow.AddDays(5),
PenaltyDays = 5,
Stages = new List<Stage>
{
new() { AmountToRelease = 1, ReleaseDate = DateTime.UtcNow.AddDays(1) },
Expand Down
6 changes: 3 additions & 3 deletions src/Angor.Test/ProtocolNew/SeederTransactionActionsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,14 @@ public void BuildRecoverSeederFundsTransactions_CallsBuildUpfrontRecoverFundsTra
var investmentTrxHex = "010000000102df7eb0603e53da8760b6037cca974550e85489d36d59efcedb8834bb691a71000000006a473044022047870ec27da9e51c3f4657b6ac376bb240191b93b1c597775f092a3c6e20e66602203f544e972f45e796730c02942393f9b7d02b4d6dc2301281c68029e693194549012103d418fd52b6bd5fc9330c51aa4480aa9f3bba2940bedc7ce7535ac164aebc25efffffffff06c0c62d0000000000160014b81698f9e2e78fa7fc87f8009183c8a4ab25a6c70000000000000000446a2103eb7d47c80390672435987b9a7ecaa22730cd9c4537fc8d257417fb058248ed7720fcdcd57c6c65b40bcdf9b454a96891d7375a60d516e3416af61f86d4999d44e180c3c901000000002251204f3edc853deba516c82aa9479daaddbe5c34bdde1b2a7be369d784e560271123804a5d0500000000225120d2f4094dc5c80bee991b76b089f230f086edfcef20550467026f80e79647b3f900879303000000002251208ea1c42515559fd53f811b333be518484aeecf9409aefeccb8e977b43ae1d9c99c547e6d00000000160014333a905154f56ef18b6f7aee53ed45a231da54f700000000";

var investmentTrx = Networks.Bitcoin.Testnet().Consensus.ConsensusFactory.CreateTransaction(investmentTrxHex);
var penaltyDate = DateTime.Now.AddMonths(6);
var penaltyDays = 180;
var receiveAddress = Encoders.Hex.EncodeData(changeAddress.PubKey.ToBytes());
var newProject = new ProjectInfo();

var recoveryTransactions = _sut.BuildRecoverSeederFundsTransaction(newProject, investmentTrx, penaltyDate,
var recoveryTransactions = _sut.BuildRecoverSeederFundsTransaction(newProject, investmentTrx, penaltyDays,
receiveAddress);

_investmentTransactionBuilder.Verify(_ => _.BuildUpfrontRecoverFundsTransaction(newProject, investmentTrx,penaltyDate,receiveAddress),
_investmentTransactionBuilder.Verify(_ => _.BuildUpfrontRecoverFundsTransaction(newProject, investmentTrx,penaltyDays,receiveAddress),
Times.Once);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ public InvestmentTransactionBuilderTest()

_sut = new InvestmentTransactionBuilder(_networkConfiguration.Object,
_projectScriptsBuilder.Object,
_investmentScriptBuilder.Object);
_investmentScriptBuilder.Object,
new TaprootScriptBuilder());
}

private Script GivenTheAngorFeeScript(ProjectInfo projectInvestmentInfo)
Expand Down Expand Up @@ -117,10 +118,10 @@ public void BuildRecoverSeederFundsTransactions_AllTransactionsReturnedWithStage

var investmentTrx = Networks.Bitcoin.Testnet().Consensus.ConsensusFactory.CreateTransaction(investmentTrxHex);

_investmentScriptBuilder.Setup(_ => _.GetInvestorPenaltyTransactionScript(It.IsAny<string>(), It.IsAny<DateTime>()))
_investmentScriptBuilder.Setup(_ => _.GetInvestorPenaltyTransactionScript(It.IsAny<string>(), It.IsAny<int>()))
.Returns(new Key().ScriptPubKey);

var recoveryTransaction = _sut.BuildUpfrontRecoverFundsTransaction(new ProjectInfo { Stages = new List<Stage> { new Stage(), new Stage(), new Stage() } }, investmentTrx, DateTime.Now.AddMonths(6),
var recoveryTransaction = _sut.BuildUpfrontRecoverFundsTransaction(new ProjectInfo { Stages = new List<Stage> { new Stage(), new Stage(), new Stage() } }, investmentTrx, 180,
Encoders.Hex.EncodeData(changeAddress.PubKey.ToBytes()));

//All inputs are from the investment transaction outputs
Expand All @@ -137,14 +138,14 @@ public void BuildRecoverSeederFundsTransactions_AllTransactionsReturnedWithTheRi
var investmentTrx = Networks.Bitcoin.Testnet().Consensus.ConsensusFactory.CreateTransaction(investmentTrxHex);

var expectedAddress = Encoders.Hex.EncodeData(changeAddress.PubKey.ToBytes());
var expectedDateTime = DateTime.Now.AddMonths(6);
var expectedDays = 180;
var expectedScript = new Key().ScriptPubKey;

_investmentScriptBuilder.Setup(_ => _.GetInvestorPenaltyTransactionScript(expectedAddress, expectedDateTime))
_investmentScriptBuilder.Setup(_ => _.GetInvestorPenaltyTransactionScript(expectedAddress, expectedDays))
.Returns(expectedScript);

var recoveryTransaction = _sut.BuildUpfrontRecoverFundsTransaction(new ProjectInfo { Stages = new List<Stage> { new Stage(), new Stage(), new Stage() } }, investmentTrx,
expectedDateTime, expectedAddress);
expectedDays, expectedAddress);

//All outputs pay to the penalty script
Assert.Contains(recoveryTransaction.Outputs,
Expand Down
2 changes: 1 addition & 1 deletion src/Angor.Test/ScriptTest.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Angor.Shared;
using Angor.Shared.Models;
using Angor.Shared.Networks;
using Angor.Shared.Protocol;
using Angor.Test.DataBuilders;
using Blockcore.NBitcoin;
using Blockcore.NBitcoin.Crypto;

Expand Down
1 change: 1 addition & 0 deletions src/Angor.Test/ScriptThresholdTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Angor.Shared;
using Angor.Test.DataBuilders;

namespace Angor.Test
{
Expand Down
4 changes: 2 additions & 2 deletions src/Angor.Test/WalletOperationsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public WalletOperationsTest()
new InvestmentScriptBuilder(new SeederScriptTreeBuilder()),
new ProjectScriptsBuilder(_derivationOperations),
new SpendingTransactionBuilder(_networkConfiguration.Object, new ProjectScriptsBuilder(_derivationOperations), new InvestmentScriptBuilder(new SeederScriptTreeBuilder())),
new InvestmentTransactionBuilder(_networkConfiguration.Object, new ProjectScriptsBuilder(_derivationOperations), new InvestmentScriptBuilder(new SeederScriptTreeBuilder())),
new InvestmentTransactionBuilder(_networkConfiguration.Object, new ProjectScriptsBuilder(_derivationOperations), new InvestmentScriptBuilder(new SeederScriptTreeBuilder()), new TaprootScriptBuilder()),
new TaprootScriptBuilder(),
_networkConfiguration.Object);

Expand Down Expand Up @@ -150,7 +150,7 @@ public void AddInputsAndSignTransaction()
projectInfo.TargetAmount = 3;
projectInfo.StartDate = DateTime.UtcNow;
projectInfo.ExpiryDate = DateTime.UtcNow.AddDays(5);
projectInfo.PenaltyDate= DateTime.UtcNow.AddDays(10);
projectInfo.PenaltyDays= 10;
projectInfo.Stages = new List<Stage>
{
new Stage { AmountToRelease = 1, ReleaseDate = DateTime.UtcNow.AddDays(1) },
Expand Down
6 changes: 3 additions & 3 deletions src/Angor/Client/NetworkConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public static List<ProjectInfo> CreateFakeProjects()
new ProjectInfo
{
StartDate = DateTime.UtcNow,
PenaltyDate = DateTime.UtcNow,
PenaltyDays = 100,
ExpiryDate = DateTime.UtcNow,
TargetAmount = 300,
ProjectIdentifier = "angor" + Guid.NewGuid().ToString("N"),
Expand All @@ -73,7 +73,7 @@ public static List<ProjectInfo> CreateFakeProjects()
new ProjectInfo
{
StartDate = DateTime.UtcNow,
PenaltyDate = DateTime.UtcNow,
PenaltyDays = 100,
ExpiryDate = DateTime.UtcNow,
TargetAmount = 200,
ProjectIdentifier = "angor" + Guid.NewGuid().ToString("N"),
Expand All @@ -87,7 +87,7 @@ public static List<ProjectInfo> CreateFakeProjects()
new ProjectInfo
{
StartDate = DateTime.UtcNow,
PenaltyDate = DateTime.UtcNow,
PenaltyDays = 100,
ExpiryDate = DateTime.UtcNow,
TargetAmount = 100,
ProjectIdentifier = "angor" + Guid.NewGuid().ToString("N"),
Expand Down
4 changes: 2 additions & 2 deletions src/Angor/Client/Pages/CheckTransactionCode.razor
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ else
},
ExpiryDate = DateTime.Now.AddDays(1),
FounderKey = Encoders.Hex.EncodeData(privateFounderKey.Neuter().PubKey.ToBytes()),
PenaltyDate = DateTime.Now.AddMinutes(1000),
PenaltyDays = 100,
StartDate = DateTime.Now,
TargetAmount = 10,
ProjectIdentifier = derivationOperations.DeriveAngorKey(Encoders.Hex.EncodeData(privateFounderKey.Neuter().PubKey.ToBytes()),angorRootKey),
Expand All @@ -172,7 +172,7 @@ else

context.TransactionHex = transaction.ToHex();

recoveryTransaction = SeederTransactionActions.BuildRecoverSeederFundsTransaction(context.ProjectInfo, transaction, context.ProjectInfo.PenaltyDate, testAddress.PubKey.ToHex());
recoveryTransaction = SeederTransactionActions.BuildRecoverSeederFundsTransaction(context.ProjectInfo, transaction, context.ProjectInfo.PenaltyDays, testAddress.PubKey.ToHex());

var signatures = FounderTransactionActions.SignInvestorRecoveryTransactions(context.ProjectInfo, context.TransactionHex, recoveryTransaction, Encoders.Hex.EncodeData(privateFounderKey.PrivateKey.ToBytes()));

Expand Down
8 changes: 4 additions & 4 deletions src/Angor/Client/Pages/Create.razor
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@

<!-- Penalty Date -->
<div class="mb-3">
<label for="penaltyDate" class="form-label">Penalty Date</label>
<InputDate id="penaltyDate" @bind-Value="project.PenaltyDate" class="form-control"/>
<label for="penaltyDays" class="form-label">Penalty Days</label>
<InputNumber id="penaltyDays" @bind-Value="project.PenaltyDays" class="form-control" />
</div>

<!-- Expiry Date -->
Expand Down Expand Up @@ -160,7 +160,7 @@

<p class="mb-1"><strong>Start date:</strong> @project.StartDate.ToString("dd/MM/yyyy") in @((project.StartDate - DateTime.Now).Days) days</p>
<p class="mb-1"><strong>Expiry date:</strong> @project.ExpiryDate.ToString("dd/MM/yyyy") in @((project.ExpiryDate - DateTime.Now).Days) days</p>
<p class="mb-1"><strong>Penalty date:</strong> @project.PenaltyDate.ToString("dd/MM/yyyy") in @((project.PenaltyDate - DateTime.Now).Days) days</p>
<p class="mb-1"><strong>Penalty days:</strong> @project.PenaltyDays days</p>

<p class="mb-1"><strong>Miner fee:</strong> [Your fee here]</p>
<p class="mb-1"><strong>Angor fee:</strong> 1000 sats</p>
Expand Down Expand Up @@ -213,7 +213,7 @@
private ProjectInfo project = new ProjectInfo
{
StartDate = DateTime.UtcNow,
PenaltyDate = DateTime.UtcNow.AddDays(100),
PenaltyDays = 100,
ExpiryDate = DateTime.UtcNow.AddDays(50),
TargetAmount = 100,
CreationTransactionId = "unknowen",
Expand Down
Loading
Loading