Skip to content

Commit 2765e50

Browse files
committed
Fix for bug in unspent parsing
1 parent 98916a6 commit 2765e50

File tree

5 files changed

+165
-96
lines changed

5 files changed

+165
-96
lines changed

Neo.Lux.Demo/Neo.Lux.Demo.csproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@
4848
</ProjectReference>
4949
</ItemGroup>
5050
<ItemGroup>
51-
<Reference Include="LunarParser, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
52-
<HintPath>..\packages\LunarParser.1.1.0\lib\net461\LunarParser.dll</HintPath>
51+
<Reference Include="LunarParser, Version=1.1.2.0, Culture=neutral, processorArchitecture=MSIL">
52+
<HintPath>..\packages\LunarParser.1.1.2\lib\net461\LunarParser.dll</HintPath>
5353
</Reference>
5454
</ItemGroup>
5555
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

Neo.Lux.Demo/packages.config

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<packages>
3-
<package id="LunarParser" version="1.1.0" targetFramework="net461" />
3+
<package id="LunarParser" version="1.1.2" targetFramework="net461" />
44
</packages>

Neo.Lux/Core/NeoAPI.cs

+157-89
Original file line numberDiff line numberDiff line change
@@ -441,10 +441,35 @@ public static byte[] GenerateScript(UInt160 scriptHash, object[] args, bool addN
441441
public void GenerateInputsOutputs(KeyPair key, string symbol, IEnumerable<Transaction.Output> targets, out List<Transaction.Input> inputs, out List<Transaction.Output> outputs, decimal system_fee = 0)
442442
{
443443
var from_script_hash = new UInt160(key.signatureHash.ToArray());
444-
GenerateInputsOutputs(from_script_hash, symbol, targets, out inputs, out outputs, system_fee);
444+
var info = GetAssetsInfo();
445+
var targetAssetID = LuxUtils.ReverseHex(info[symbol]).HexToBytes();
446+
if (targets != null)
447+
foreach (var t in targets)
448+
if (t.assetID == null)
449+
t.assetID = targetAssetID;
450+
//else Console.WriteLine("ASSETID target already existed: " + symbol);
451+
GenerateInputsOutputs(from_script_hash, targets, out inputs, out outputs, system_fee);
445452
}
446453

447-
public void GenerateInputsOutputs(UInt160 from_script_hash, string symbol, IEnumerable<Transaction.Output> targets, out List<Transaction.Input> inputs, out List<Transaction.Output> outputs, decimal system_fee = 0)
454+
public void GenerateInputsOutputs(UInt160 key, string symbol, IEnumerable<Transaction.Output> targets, out List<Transaction.Input> inputs, out List<Transaction.Output> outputs, decimal system_fee = 0)
455+
{
456+
var info = GetAssetsInfo();
457+
var targetAssetID = LuxUtils.ReverseHex(info[symbol]).HexToBytes();
458+
if (targets != null)
459+
foreach (var t in targets)
460+
if (t.assetID == null)
461+
t.assetID = targetAssetID;
462+
// else Console.WriteLine("ASSETID target already existed: " + symbol);
463+
GenerateInputsOutputs(key, symbol, targets, out inputs, out outputs, system_fee);
464+
}
465+
466+
public void GenerateInputsOutputs(KeyPair key, IEnumerable<Transaction.Output> targets, out List<Transaction.Input> inputs, out List<Transaction.Output> outputs, decimal system_fee = 0)
467+
{
468+
var from_script_hash = new UInt160(key.signatureHash.ToArray());
469+
GenerateInputsOutputs(from_script_hash, targets, out inputs, out outputs, system_fee);
470+
}
471+
472+
public void GenerateInputsOutputs(UInt160 from_script_hash, IEnumerable<Transaction.Output> targets, out List<Transaction.Input> inputs, out List<Transaction.Output> outputs, decimal system_fee = 0)
448473
{
449474
var unspent = GetUnspent(from_script_hash);
450475
// filter any asset lists with zero unspent inputs
@@ -453,123 +478,166 @@ public void GenerateInputsOutputs(UInt160 from_script_hash, string symbol, IEnum
453478
inputs = new List<Transaction.Input>();
454479
outputs = new List<Transaction.Output>();
455480

456-
string assetID;
457-
458-
var info = GetAssetsInfo();
459-
if (info.ContainsKey(symbol))
460-
{
461-
assetID = info[symbol];
462-
}
463-
else
464-
{
465-
throw new NeoException($"{symbol} is not a valid blockchain asset.");
466-
}
467-
468481
var from_address = from_script_hash.ToAddress();
482+
var info = GetAssetsInfo();
469483

470-
if (!unspent.ContainsKey(symbol))
484+
// dummy tx to self
485+
if (targets == null)
471486
{
472-
throw new NeoException($"Not enough {symbol} in address {from_address}");
473-
}
487+
string assetName = "GAS";
488+
string assetID = info[assetName];
489+
var targetAssetID = LuxUtils.ReverseHex(assetID).HexToBytes();
490+
if (!unspent.ContainsKey(assetName))
491+
throw new NeoException($"Not enough {assetName} in address {from_address}");
474492

475-
decimal cost = 0;
493+
var src = unspent[assetName][0];
494+
decimal selected = src.value;
495+
// Console.WriteLine("SENDING " + selected + " GAS to source");
476496

477-
if (targets != null)
478-
{
479-
foreach (var target in targets)
497+
inputs.Add(new Transaction.Input()
480498
{
481-
if (target.scriptHash.Equals(from_script_hash))
482-
{
483-
throw new NeoException("Target can't be same as input");
484-
}
499+
prevHash = src.hash,
500+
prevIndex = src.index,
501+
});
485502

486-
cost += target.value;
487-
}
503+
outputs.Add(new Transaction.Output()
504+
{
505+
assetID = targetAssetID,
506+
scriptHash = from_script_hash,
507+
value = selected
508+
});
509+
return;
488510
}
489511

490-
var targetAssetID = LuxUtils.ReverseHex(assetID).HexToBytes();
512+
foreach (var target in targets)
513+
if (target.scriptHash.Equals(from_script_hash))
514+
throw new NeoException("Target can't be same as input");
491515

492-
var sources = unspent[symbol];
493-
decimal selected = 0;
494-
495-
if (lastTransactions.ContainsKey(from_address))
516+
bool done_fee = false;
517+
foreach (var asset in info)
496518
{
497-
var lastTx = lastTransactions[from_address];
498-
499-
uint index = 0;
500-
if (lastTx.outputs != null)
501-
{
502-
foreach (var output in lastTx.outputs)
503-
{
504-
if (output.assetID.SequenceEqual(targetAssetID) && output.scriptHash.Equals(from_script_hash))
505-
{
506-
selected += output.value;
519+
string assetName = asset.Key;
520+
string assetID = asset.Value;
507521

508-
var input = new Transaction.Input()
509-
{
510-
prevHash = lastTx.Hash,
511-
prevIndex = index,
512-
};
522+
if (!unspent.ContainsKey(assetName))
523+
continue;
513524

514-
inputs.Add(input);
525+
var targetAssetID = LuxUtils.ReverseHex(assetID).HexToBytes();
515526

516-
break;
517-
}
527+
var thistargets = targets.Where(o => o.assetID.SequenceEqual(targetAssetID));
518528

519-
index++;
529+
decimal cost = -1;
530+
foreach (var target in thistargets)
531+
if (target.assetID.SequenceEqual(targetAssetID))
532+
{
533+
if (cost < 0)
534+
cost = 0;
535+
cost += target.value;
520536
}
521-
}
522-
}
523537

524-
foreach (var src in sources)
525-
{
526-
if (selected >= cost && inputs.Count > 0)
538+
// incorporate fee in GAS utxo, if sending GAS
539+
bool sendfee = false;
540+
if (system_fee > 0 && assetName == "GAS")
527541
{
528-
break;
542+
done_fee = true;
543+
sendfee = true;
544+
if (cost < 0)
545+
cost = 0;
546+
cost += system_fee;
529547
}
530548

531-
selected += src.value;
549+
if (cost == -1)
550+
continue;
551+
552+
var sources = unspent[assetName].OrderBy(src => src.value);
553+
decimal selected = 0;
532554

533-
var input = new Transaction.Input()
555+
// >= cost ou > cost??
556+
foreach (var src in sources)
534557
{
535-
prevHash = src.hash,
536-
prevIndex = src.index,
537-
};
558+
if (selected >= cost && inputs.Count > 0)
559+
break;
538560

539-
inputs.Add(input);
540-
}
561+
selected += src.value;
562+
inputs.Add(new Transaction.Input()
563+
{
564+
prevHash = src.hash,
565+
prevIndex = src.index,
566+
});
567+
// Console.WriteLine("ADD inp " + src.ToString());
568+
}
541569

542-
if (selected < cost)
543-
{
544-
throw new NeoException($"Not enough {symbol}");
545-
}
570+
if (selected < cost)
571+
throw new NeoException($"Not enough {assetName} in address {from_address}");
546572

547-
if (cost > 0 && targets != null)
548-
{
549-
foreach (var target in targets)
550-
{
551-
var output = new Transaction.Output()
573+
if (cost > 0)
574+
foreach (var target in thistargets)
575+
outputs.Add(target);
576+
577+
if (selected > cost || cost == 0 || sendfee) /// is sendfee needed? yes if selected == cost
578+
outputs.Add(new Transaction.Output()
552579
{
553580
assetID = targetAssetID,
554-
scriptHash = target.scriptHash,
555-
value = target.value
556-
};
557-
outputs.Add(output);
558-
}
581+
scriptHash = from_script_hash,
582+
value = selected - cost
583+
});
559584
}
585+
/*
586+
if (system_fee > 0 && !done_fee && false)
587+
{
588+
var gasID = LuxUtils.ReverseHex(info["GAS"]).HexToBytes();
589+
var gassources = unspent["GAS"];
590+
// foreach (var src in gassources)
591+
// Console.WriteLine("SRC: " + src.ToString());
592+
decimal feeselected = 0;
593+
foreach (var src in gassources)
594+
if (feeselected <= system_fee)
595+
{
596+
inputs.Add(new Transaction.Input()
597+
{
598+
prevHash = src.hash,
599+
prevIndex = src.index,
600+
});
601+
feeselected += src.value;
602+
Console.WriteLine("add input " + feeselected);
603+
break;
604+
}
605+
outputs.Add(new Transaction.Output()
606+
{
607+
assetID = gasID,
608+
scriptHash = from_script_hash,
609+
value = feeselected - system_fee
610+
});
611+
}
560612
561-
if (selected > cost || cost == 0)
562-
{
563-
var left = selected - cost;
613+
foreach (var i in inputs)
614+
Console.WriteLine("INPUT " + i);
615+
foreach (var i in output)
616+
Console.WriteLine("OUTPUT " + i);
617+
// chaining
618+
if (lastTransactions.ContainsKey(from_address))
619+
{
620+
var lastTx = lastTransactions[from_address];
621+
uint index = 0;
622+
if (lastTx.outputs != null)
623+
foreach (var output in lastTx.outputs)
624+
{
625+
if (output.assetID.SequenceEqual(targetAssetID) && output.scriptHash.Equals(from_script_hash))
626+
{
627+
selected += output.value;
628+
var input = new Transaction.Input()
629+
{
630+
prevHash = lastTx.Hash,
631+
prevIndex = index,
632+
};
633+
inputs.Add(input);
634+
break;
635+
}
636+
index++;
637+
}
638+
}
639+
*/
564640

565-
var change = new Transaction.Output()
566-
{
567-
assetID = targetAssetID,
568-
scriptHash = from_script_hash,
569-
value = left
570-
};
571-
outputs.Add(change);
572-
}
573641
}
574642

575643
public Transaction CallContract(KeyPair key, UInt160 scriptHash, object[] args, string attachSymbol = null, IEnumerable<Transaction.Output> attachTargets = null)

Neo.Lux/Core/NeoRPC.cs

+4-3
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ public DataNode QueryRPC(string method, object[] _params, int id = 1)
5353
}
5454

5555
var jsonRpcData = DataNode.CreateObject(null);
56+
jsonRpcData.AddField("jsonrpc", "2.0");
5657
jsonRpcData.AddField("method", method);
5758
jsonRpcData.AddNode(paramData);
5859
jsonRpcData.AddField("id", id);
59-
jsonRpcData.AddField("jsonrpc", "2.0");
6060

6161
Logger("QueryRPC: " + method);
6262
LogData(jsonRpcData);
@@ -151,7 +151,8 @@ public override Dictionary<string, List<UnspentEntry>> GetUnspent(UInt160 hash)
151151
foreach (var entry in unspentNode.Children)
152152
{
153153
var txid = entry.GetString("txid");
154-
var temp = new UnspentEntry() { hash = new UInt256(LuxUtils.ReverseHex(txid).HexToBytes()), value = entry.GetDecimal("value"), index = entry.GetUInt32("n") };
154+
var val = entry.GetDecimal("value");
155+
var temp = new UnspentEntry() { hash = new UInt256(LuxUtils.ReverseHex(txid).HexToBytes()), value = val, index = entry.GetUInt32("n") };
155156
list.Add(temp);
156157
}
157158
}
@@ -186,7 +187,7 @@ public override List<UnspentEntry> GetClaimable(UInt160 hash, out decimal amount
186187

187188
public bool SendRawTransaction(string hexTx)
188189
{
189-
var response = QueryRPC("sendrawtransaction", new object[] {hexTx });
190+
var response = QueryRPC("sendrawtransaction", new object[] {hexTx }, 12);
190191
if (response == null)
191192
{
192193
throw new Exception("Connection failure");

Neo.Lux/Neo.Lux.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545

4646
<ItemGroup>
4747
<PackageReference Include="BouncyCastle" Version="1.8.2" />
48-
<PackageReference Include="LunarParser" Version="1.1.0" />
48+
<PackageReference Include="LunarParser" Version="1.1.2" />
4949
</ItemGroup>
5050

5151
<ItemGroup>

0 commit comments

Comments
 (0)