Skip to content
This repository was archived by the owner on Dec 7, 2023. It is now read-only.

Commit 588f1e6

Browse files
superboyiiishargon
andauthored
add cancel command for conflict attribute (#903)
* add cancel command for conflict attribute * fix some comment * fix no-wallet * format * Clean and use cheaper OpCode --------- Co-authored-by: Shargon <[email protected]>
1 parent 29d1aa9 commit 588f1e6

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed

neo-cli/CLI/MainService.Wallet.cs

+83
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using Neo.Persistence;
1717
using Neo.SmartContract;
1818
using Neo.SmartContract.Native;
19+
using Neo.VM;
1920
using Neo.Wallets;
2021
using Neo.Wallets.NEP6;
2122
using System;
@@ -559,6 +560,88 @@ private void OnSendCommand(UInt160 asset, UInt160 to, string amount, UInt160 fro
559560
SignAndSendTx(NeoSystem.StoreView, tx);
560561
}
561562

563+
/// <summary>
564+
/// Process "cancel" command
565+
/// </summary>
566+
/// <param name="txid">conflict txid</param>
567+
/// <param name="sender">Transaction's sender</param>
568+
/// <param name="signerAccounts">Signer's accounts</param>
569+
[ConsoleCommand("cancel", Category = "Wallet Commands")]
570+
private void OnCancelCommand(UInt256 txid, UInt160 sender = null, UInt160[] signerAccounts = null)
571+
{
572+
TransactionState state = NativeContract.Ledger.GetTransactionState(NeoSystem.StoreView, txid);
573+
if (state != null)
574+
{
575+
ConsoleHelper.Error("This tx is already confirmed, can't be cancelled.");
576+
return;
577+
}
578+
579+
var conflict = new TransactionAttribute[] { new Conflicts() { Hash = txid } };
580+
Signer[] signers = Array.Empty<Signer>();
581+
if (!NoWallet() && sender != null)
582+
{
583+
if (signerAccounts == null)
584+
signerAccounts = new UInt160[1] { sender };
585+
else if (signerAccounts.Contains(sender) && signerAccounts[0] != sender)
586+
{
587+
var signersList = signerAccounts.ToList();
588+
signersList.Remove(sender);
589+
signerAccounts = signersList.Prepend(sender).ToArray();
590+
}
591+
else if (!signerAccounts.Contains(sender))
592+
{
593+
signerAccounts = signerAccounts.Prepend(sender).ToArray();
594+
}
595+
signers = signerAccounts.Select(p => new Signer() { Account = p, Scopes = WitnessScope.CalledByEntry }).ToArray();
596+
}
597+
598+
Transaction tx = new Transaction
599+
{
600+
Signers = signers,
601+
Attributes = conflict,
602+
Witnesses = Array.Empty<Witness>(),
603+
};
604+
605+
try
606+
{
607+
using ScriptBuilder scriptBuilder = new();
608+
scriptBuilder.Emit(OpCode.RET);
609+
tx = CurrentWallet.MakeTransaction(NeoSystem.StoreView, scriptBuilder.ToArray(), sender, signers, conflict);
610+
}
611+
catch (InvalidOperationException e)
612+
{
613+
ConsoleHelper.Error(GetExceptionMessage(e));
614+
return;
615+
}
616+
617+
if (NeoSystem.MemPool.TryGetValue(txid, out Transaction conflictTx))
618+
{
619+
tx.NetworkFee = Math.Max(tx.NetworkFee, conflictTx.NetworkFee) + 1;
620+
}
621+
else
622+
{
623+
var snapshot = NeoSystem.StoreView;
624+
AssetDescriptor descriptor = new(snapshot, NeoSystem.Settings, NativeContract.GAS.Hash);
625+
string extracFee = ReadUserInput("This tx is not in mempool, please input extra fee manually");
626+
if (!BigDecimal.TryParse(extracFee, descriptor.Decimals, out BigDecimal decimalExtraFee) || decimalExtraFee.Sign <= 0)
627+
{
628+
ConsoleHelper.Error("Incorrect Amount Format");
629+
return;
630+
}
631+
tx.NetworkFee += (long)decimalExtraFee.Value;
632+
};
633+
634+
ConsoleHelper.Info("Network fee: ",
635+
$"{new BigDecimal((BigInteger)tx.NetworkFee, NativeContract.GAS.Decimals)}\t",
636+
"Total fee: ",
637+
$"{new BigDecimal((BigInteger)(tx.SystemFee + tx.NetworkFee), NativeContract.GAS.Decimals)} GAS");
638+
if (!ReadUserInput("Relay tx? (no|yes)").IsYes())
639+
{
640+
return;
641+
}
642+
SignAndSendTx(NeoSystem.StoreView, tx);
643+
}
644+
562645
/// <summary>
563646
/// Process "show gas" command
564647
/// </summary>

0 commit comments

Comments
 (0)