Skip to content

Commit

Permalink
remove VotingTransaction; display unavailable ANC; optimize the proce…
Browse files Browse the repository at this point in the history
…ss of voting; fix bug; use antcha.in as blockchain explorer;
  • Loading branch information
Erik Zhang committed Oct 20, 2016
1 parent cbd5d4a commit 1db0a21
Show file tree
Hide file tree
Showing 28 changed files with 1,289 additions and 1,231 deletions.
1 change: 0 additions & 1 deletion AntSharesCore/AntSharesCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,6 @@
<Compile Include="Core\TransactionResult.cs" />
<Compile Include="Core\TransactionType.cs" />
<Compile Include="Core\Vote.cs" />
<Compile Include="Core\VotingTransaction.cs" />
<Compile Include="Cryptography\Helper.cs" />
<Compile Include="Cryptography\MerkleTree.cs" />
<Compile Include="Fixed8.cs" />
Expand Down
11 changes: 0 additions & 11 deletions AntSharesCore/Core/Scripts/InterfaceEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ public bool Invoke(string method, ScriptEngine engine)
return AssetAdmin(engine);
case "AntShares.Enroll.pubkey":
return EnrollPubkey(engine);
case "AntShares.Vote.enrollments":
return VoteEnrollments(engine);
case "AntShares.TX.attributes":
return TxAttributes(engine);
case "AntShares.TX.inputs":
Expand Down Expand Up @@ -447,15 +445,6 @@ private bool EnrollPubkey(ScriptEngine engine)
return true;
}

private bool VoteEnrollments(ScriptEngine engine)
{
if (engine.AltStack.Count < 1) return false;
VotingTransaction tx = engine.AltStack.Pop().GetInterface<VotingTransaction>();
if (tx == null) return false;
engine.Stack.Push(new StackItem(tx.Enrollments));
return true;
}

private bool TxAttributes(ScriptEngine engine)
{
if (engine.AltStack.Count < 1) return false;
Expand Down
27 changes: 22 additions & 5 deletions AntSharesCore/Core/Transaction.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using AntShares.Core.Scripts;
using AntShares.Cryptography;
using AntShares.Cryptography.ECC;
using AntShares.IO;
using AntShares.IO.Json;
using AntShares.Network;
Expand Down Expand Up @@ -169,16 +170,20 @@ private void DeserializeUnsignedWithoutType(BinaryReader reader)
throw new FormatException();
DeserializeExclusiveData(reader);
Attributes = reader.ReadSerializableArray<TransactionAttribute>();
if (Attributes.Select(p => p.Usage).Distinct().Count() != Attributes.Length)
if (Attributes.Count(p => p.Usage == TransactionAttributeUsage.ECDH02 || p.Usage == TransactionAttributeUsage.ECDH03) > 1)
throw new FormatException();
if (Attributes.Count(p => p.Usage == TransactionAttributeUsage.Vote) > 1024)
throw new FormatException();
if (Attributes.Where(p => p.Usage == TransactionAttributeUsage.Vote).Select(p => new UInt256(p.Data)).Distinct().Count() != Attributes.Count(p => p.Usage == TransactionAttributeUsage.Vote))
throw new FormatException();
Inputs = reader.ReadSerializableArray<TransactionInput>();
TransactionInput[] inputs = GetAllInputs().ToArray();
for (int i = 1; i < inputs.Length; i++)
for (int j = 0; j < i; j++)
if (inputs[i].PrevHash == inputs[j].PrevHash && inputs[i].PrevIndex == inputs[j].PrevIndex)
throw new FormatException();
Outputs = reader.ReadSerializableArray<TransactionOutput>();
if (Outputs.Length > ushort.MaxValue + 1)
Outputs = reader.ReadSerializableArray<TransactionOutput>(ushort.MaxValue + 1);
if (Attributes.Any(p => p.Usage == TransactionAttributeUsage.Vote) && Outputs.All(p => !p.AssetId.Equals(Blockchain.AntShare.Hash)))
throw new FormatException();
}

Expand Down Expand Up @@ -346,8 +351,7 @@ public virtual bool Verify()
return false;
break;
}
TransactionAttribute script = Attributes.FirstOrDefault(p => p.Usage == TransactionAttributeUsage.Script);
if (script != null)
foreach (TransactionAttribute script in Attributes.Where(p => p.Usage == TransactionAttributeUsage.Script))
{
ScriptEngine engine = new ScriptEngine(new Script
{
Expand All @@ -356,6 +360,19 @@ public virtual bool Verify()
}, this, InterfaceEngine.Default);
if (!engine.Execute()) return false;
}
if (Attributes.Any(p => p.Usage == TransactionAttributeUsage.Vote))
{
if (!Blockchain.Default.Ability.HasFlag(BlockchainAbility.UnspentIndexes))
return false;
HashSet<ECPoint> pubkeys = new HashSet<ECPoint>();
foreach (UInt256 vote in Attributes.Where(p => p.Usage == TransactionAttributeUsage.Vote).Select(p => new UInt256(p.Data)))
{
EnrollmentTransaction tx = Blockchain.Default.GetTransaction(vote) as EnrollmentTransaction;
if (tx == null) return false;
if (!Blockchain.Default.ContainsUnspent(vote, 0)) return false;
if (!pubkeys.Add(tx.PublicKey)) return false;
}
}
return this.VerifySignature();
}
}
Expand Down
2 changes: 1 addition & 1 deletion AntSharesCore/Core/TransactionAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class TransactionAttribute : ISerializable
void ISerializable.Deserialize(BinaryReader reader)
{
Usage = (TransactionAttributeUsage)reader.ReadByte();
if (Usage == TransactionAttributeUsage.ContractHash || (Usage >= TransactionAttributeUsage.Hash1 && Usage <= TransactionAttributeUsage.Hash15))
if (Usage == TransactionAttributeUsage.ContractHash || Usage == TransactionAttributeUsage.Vote || (Usage >= TransactionAttributeUsage.Hash1 && Usage <= TransactionAttributeUsage.Hash15))
Data = reader.ReadBytes(32);
else if (Usage == TransactionAttributeUsage.ECDH02 || Usage == TransactionAttributeUsage.ECDH03)
Data = new[] { (byte)Usage }.Concat(reader.ReadBytes(32)).ToArray();
Expand Down
2 changes: 2 additions & 0 deletions AntSharesCore/Core/TransactionAttributeUsage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public enum TransactionAttributeUsage : byte
/// </summary>
Script = 0x20,

Vote = 0x30,

CertUrl = 0x80,
DescriptionUrl = 0x81,
Description = 0x90,
Expand Down
4 changes: 0 additions & 4 deletions AntSharesCore/Core/TransactionType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ public enum TransactionType : byte
/// </summary>
EnrollmentTransaction = 0x20,
/// <summary>
/// 用于投票选出记账人的特殊交易
/// </summary>
VotingTransaction = 0x24,
/// <summary>
/// 用于资产登记的特殊交易
/// </summary>
RegisterTransaction = 0x40,
Expand Down
94 changes: 0 additions & 94 deletions AntSharesCore/Core/VotingTransaction.cs

This file was deleted.

4 changes: 2 additions & 2 deletions AntSharesCore/IO/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ public static string ReadFixedString(this BinaryReader reader, int length)
return obj;
}

public static T[] ReadSerializableArray<T>(this BinaryReader reader) where T : ISerializable, new()
public static T[] ReadSerializableArray<T>(this BinaryReader reader, int max = 0x10000000) where T : ISerializable, new()
{
T[] array = new T[reader.ReadVarInt(0x10000000)];
T[] array = new T[reader.ReadVarInt((ulong)max)];
for (int i = 0; i < array.Length; i++)
{
array[i] = new T();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -396,19 +396,21 @@ public override IEnumerable<Vote> GetVotes(IEnumerable<Transaction> others)
UInt256 hash = new UInt256(kv.Key.ToArray().Skip(1).ToArray());
ushort[] indexes = kv.Value.ToArray().GetUInt16Array().Except(others.SelectMany(p => p.GetAllInputs()).Where(p => p.PrevHash == hash).Select(p => p.PrevIndex)).ToArray();
if (indexes.Length == 0) continue;
VotingTransaction tx = (VotingTransaction)GetTransaction(options, hash, out height);
Transaction tx = GetTransaction(options, hash, out height);
yield return new Vote
{
Enrollments = tx.Enrollments,
Enrollments = tx.Attributes.Where(p => p.Usage == TransactionAttributeUsage.Vote).Select(p => new UInt256(p.Data)).ToArray(),
Count = indexes.Sum(p => tx.Outputs[p].Value)
};
}
}
foreach (VotingTransaction tx in others.OfType<VotingTransaction>())
foreach (Transaction tx in others)
{
UInt256[] enrollments = tx.Attributes.Where(p => p.Usage == TransactionAttributeUsage.Vote).Select(p => new UInt256(p.Data)).ToArray();
if (enrollments.Length == 0) continue;
yield return new Vote
{
Enrollments = tx.Enrollments,
Enrollments = enrollments,
Count = tx.Outputs.Where(p => p.AssetId == AntShare.Hash).Sum(p => p.Value)
};
}
Expand Down Expand Up @@ -512,6 +514,17 @@ private void Persist(Block block)
foreach (Transaction tx in block.Transactions)
{
batch.Put(SliceBuilder.Begin(DataEntryPrefix.DATA_Transaction).Add(tx.Hash), SliceBuilder.Begin().Add(block.Height).Add(tx.ToArray()));
if (tx.Attributes.Any(p => p.Usage == TransactionAttributeUsage.Vote))
{
unspent_votes.AddEmpty(tx.Hash);
for (ushort index = 0; index < tx.Outputs.Length; index++)
{
if (tx.Outputs[index].AssetId == AntShare.Hash)
{
unspent_votes.Add(tx.Hash, index);
}
}
}
switch (tx.Type)
{
case TransactionType.IssueTransaction:
Expand Down Expand Up @@ -539,16 +552,6 @@ private void Persist(Block block)
batch.Put(SliceBuilder.Begin(DataEntryPrefix.IX_Enrollment).Add(tx.Hash), true);
}
break;
case TransactionType.VotingTransaction:
unspent_votes.AddEmpty(tx.Hash);
for (ushort index = 0; index < tx.Outputs.Length; index++)
{
if (tx.Outputs[index].AssetId == AntShare.Hash)
{
unspent_votes.Add(tx.Hash, index);
}
}
break;
case TransactionType.PublishTransaction:
foreach (byte[] script in ((PublishTransaction)tx).Contracts)
{
Expand Down
28 changes: 28 additions & 0 deletions AntSharesCore/Wallets/Wallet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,34 @@ public static Fixed8 CalculateClaimAmount(IEnumerable<TransactionInput> inputs)
unclaimed.Add(claimable[claim.PrevIndex]);
}
}
return CalculateClaimAmountInternal(unclaimed);
}

public static Fixed8 CalculateClaimAmountUnavailable(IEnumerable<TransactionInput> inputs, uint height)
{
List<Claimable> unclaimed = new List<Claimable>();
foreach (var group in inputs.GroupBy(p => p.PrevHash))
{
int height_start;
Transaction tx = Blockchain.Default.GetTransaction(group.Key, out height_start);
if (tx == null) throw new ArgumentException();
foreach (TransactionInput claim in group)
{
if (claim.PrevIndex >= tx.Outputs.Length || !tx.Outputs[claim.PrevIndex].AssetId.Equals(Blockchain.AntShare.Hash))
throw new ArgumentException();
unclaimed.Add(new Claimable
{
Output = tx.Outputs[claim.PrevIndex],
StartHeight = (uint)height_start,
EndHeight = height
});
}
}
return CalculateClaimAmountInternal(unclaimed);
}

private static Fixed8 CalculateClaimAmountInternal(IEnumerable<Claimable> unclaimed)
{
Fixed8 amount_claimed = Fixed8.Zero;
foreach (var group in unclaimed.GroupBy(p => new { p.StartHeight, p.EndHeight }))
{
Expand Down
11 changes: 9 additions & 2 deletions AntSharesDaemon/Network/RPC/RpcServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,22 @@ private JObject InternalCall(string method, JArray _params)
{
UInt256 hash = UInt256.Parse(_params[0].AsString());
bool verbose = _params.Count >= 2 && _params[1].AsBooleanOrDefault(false);
int height = -1;
Transaction tx = LocalNode.GetTransaction(hash);
if (tx == null)
tx = Blockchain.Default.GetTransaction(hash);
tx = Blockchain.Default.GetTransaction(hash, out height);
if (tx == null)
throw new RpcException(-101, "Unknown transaction");
if (verbose)
return tx.ToJson();
{
JObject json = tx.ToJson();
json["height"] = height;
return json;
}
else
{
return tx.ToArray().ToHexString();
}
}
case "gettxout":
{
Expand Down
Loading

0 comments on commit 1db0a21

Please sign in to comment.