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

Store TX result inside block #716

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions neo/Consensus/ConsensusContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,12 @@ public Block CreateBlock()
j++;
}
Block.Witness = sc.GetWitnesses()[0];
Block.Transactions = TransactionHashes.Select(p => Transactions[p]).ToArray();
Block.Transactions = TransactionHashes.Select(p => new ExecutedTransaction()
{
Transaction = Transactions[p]
// TODO: Get result state
})
.ToArray();
}
return Block;
}
Expand Down Expand Up @@ -169,7 +174,7 @@ public Block MakeHeader()
Index = BlockIndex,
ConsensusData = Nonce,
NextConsensus = NextConsensus,
Transactions = new Transaction[0]
Transactions = new ExecutedTransaction[0]
};
}
return _header;
Expand Down Expand Up @@ -305,7 +310,7 @@ public void Reset(byte viewNumber)
Timestamp = 0;
TransactionHashes = null;
PreparationPayloads = new ConsensusPayload[Validators.Length];
if (MyIndex >= 0) LastSeenMessage[MyIndex] = (int) BlockIndex;
if (MyIndex >= 0) LastSeenMessage[MyIndex] = (int)BlockIndex;
_header = null;
}

Expand Down
94 changes: 54 additions & 40 deletions neo/Ledger/Blockchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,39 +75,53 @@ public class FillCompleted { }
InvocationScript = new byte[0],
VerificationScript = new[] { (byte)OpCode.PUSHT }
},
Transactions = new Transaction[]
Transactions = new ExecutedTransaction[]
{
new MinerTransaction
new ExecutedTransaction()
{
Nonce = 2083236893,
Attributes = new TransactionAttribute[0],
Inputs = new CoinReference[0],
Outputs = new TransactionOutput[0],
Witnesses = new Witness[0]
Transaction = new MinerTransaction
{
Nonce = 2083236893,
Attributes = new TransactionAttribute[0],
Inputs = new CoinReference[0],
Outputs = new TransactionOutput[0],
Witnesses = new Witness[0]
},
State = VMState.HALT
},
new ExecutedTransaction()
{
Transaction = GoverningToken, State= VMState.HALT
},
GoverningToken,
UtilityToken,
new IssueTransaction
new ExecutedTransaction()
{
Attributes = new TransactionAttribute[0],
Inputs = new CoinReference[0],
Outputs = new[]
Transaction = UtilityToken, State= VMState.HALT
},
new ExecutedTransaction()
{
Transaction = new IssueTransaction
{
new TransactionOutput
Attributes = new TransactionAttribute[0],
Inputs = new CoinReference[0],
Outputs = new[]
{
AssetId = GoverningToken.Hash,
Value = GoverningToken.Amount,
ScriptHash = Contract.CreateMultiSigRedeemScript(StandbyValidators.Length / 2 + 1, StandbyValidators).ToScriptHash()
}
},
Witnesses = new[]
{
new Witness
new TransactionOutput
{
AssetId = GoverningToken.Hash,
Value = GoverningToken.Amount,
ScriptHash = Contract.CreateMultiSigRedeemScript(StandbyValidators.Length / 2 + 1, StandbyValidators).ToScriptHash()
}
},
Witnesses = new[]
{
InvocationScript = new byte[0],
VerificationScript = new[] { (byte)OpCode.PUSHT }
new Witness
{
InvocationScript = new byte[0],
VerificationScript = new[] { (byte)OpCode.PUSHT }
}
}
}
},
State = VMState.HALT
}
}
};
Expand Down Expand Up @@ -313,7 +327,7 @@ private RelayResultReason OnNewBlock(Block block)
block_cache_unverified.Remove(blockToPersist.Index);
Persist(blockToPersist);

if (blocksPersisted++ < blocksToPersistList.Count - (2 + Math.Max(0,(15 - SecondsPerBlock)))) continue;
if (blocksPersisted++ < blocksToPersistList.Count - (2 + Math.Max(0, (15 - SecondsPerBlock)))) continue;
// Empirically calibrated for relaying the most recent 2 blocks persisted with 15s network
// Increase in the rate of 1 block per second in configurations with faster blocks

Expand Down Expand Up @@ -453,21 +467,21 @@ private void Persist(Block block)
snapshot.PersistingBlock = block;
snapshot.Blocks.Add(block.Hash, new BlockState
{
SystemFeeAmount = snapshot.GetSysFeeAmount(block.PrevHash) + (long)block.Transactions.Sum(p => p.SystemFee),
SystemFeeAmount = snapshot.GetSysFeeAmount(block.PrevHash) + (long)block.Transactions.Sum(p => p.Transaction.SystemFee),
TrimmedBlock = block.Trim()
});
foreach (Transaction tx in block.Transactions)
foreach (var tx in block.Transactions)
{
snapshot.Transactions.Add(tx.Hash, new TransactionState
snapshot.Transactions.Add(tx.Transaction.Hash, new TransactionState
{
BlockIndex = block.Index,
Transaction = tx
Transaction = tx.Transaction
});
snapshot.UnspentCoins.Add(tx.Hash, new UnspentCoinState
snapshot.UnspentCoins.Add(tx.Transaction.Hash, new UnspentCoinState
{
Items = Enumerable.Repeat(CoinState.Confirmed, tx.Outputs.Length).ToArray()
Items = Enumerable.Repeat(CoinState.Confirmed, tx.Transaction.Outputs.Length).ToArray()
});
foreach (TransactionOutput output in tx.Outputs)
foreach (TransactionOutput output in tx.Transaction.Outputs)
{
AccountState account = snapshot.Accounts.GetAndChange(output.ScriptHash, () => new AccountState(output.ScriptHash));
if (account.Balances.ContainsKey(output.AssetId))
Expand All @@ -481,7 +495,7 @@ private void Persist(Block block)
snapshot.ValidatorsCount.GetAndChange().Votes[account.Votes.Length - 1] += output.Value;
}
}
foreach (var group in tx.Inputs.GroupBy(p => p.PrevHash))
foreach (var group in tx.Transaction.Inputs.GroupBy(p => p.PrevHash))
{
TransactionState tx_prev = snapshot.Transactions[group.Key];
foreach (CoinReference input in group)
Expand Down Expand Up @@ -513,11 +527,11 @@ private void Persist(Block block)
}
}
List<ApplicationExecutionResult> execution_results = new List<ApplicationExecutionResult>();
switch (tx)
switch (tx.Transaction)
{
#pragma warning disable CS0612
case RegisterTransaction tx_register:
snapshot.Assets.Add(tx.Hash, new AssetState
snapshot.Assets.Add(tx.Transaction.Hash, new AssetState
{
AssetId = tx_register.Hash,
AssetType = tx_register.AssetType,
Expand All @@ -536,11 +550,11 @@ private void Persist(Block block)
break;
#pragma warning restore CS0612
case IssueTransaction _:
foreach (TransactionResult result in tx.GetTransactionResults().Where(p => p.Amount < Fixed8.Zero))
foreach (TransactionResult result in tx.Transaction.GetTransactionResults().Where(p => p.Amount < Fixed8.Zero))
snapshot.Assets.GetAndChange(result.AssetId).Available -= result.Amount;
break;
case ClaimTransaction _:
foreach (CoinReference input in ((ClaimTransaction)tx).Claims)
foreach (CoinReference input in ((ClaimTransaction)tx.Transaction).Claims)
{
if (snapshot.SpentCoins.TryGet(input.PrevHash)?.Items.Remove(input.PrevIndex) == true)
snapshot.SpentCoins.GetAndChange(input.PrevHash);
Expand Down Expand Up @@ -602,9 +616,9 @@ private void Persist(Block block)
}
if (execution_results.Count > 0)
{
ApplicationExecuted application_executed = new ApplicationExecuted
var application_executed = new ApplicationExecuted
{
Transaction = tx,
Transaction = tx.Transaction,
ExecutionResults = execution_results.ToArray()
};
Context.System.EventStream.Publish(application_executed);
Expand Down
6 changes: 3 additions & 3 deletions neo/Ledger/MemoryPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -382,10 +382,10 @@ internal void UpdatePoolForBlockPersisted(Block block, Snapshot snapshot)
try
{
// First remove the transactions verified in the block.
foreach (Transaction tx in block.Transactions)
foreach (var tx in block.Transactions)
{
if (TryRemoveVerified(tx.Hash, out _)) continue;
TryRemoveUnVerified(tx.Hash, out _);
if (TryRemoveVerified(tx.Transaction.Hash, out _)) continue;
TryRemoveUnVerified(tx.Transaction.Hash, out _);
}

// Add all the previously verified transactions back to the unverified transactions
Expand Down
7 changes: 6 additions & 1 deletion neo/Ledger/TrimmedBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ public Block GetBlock(DataCache<UInt256, TransactionState> cache)
ConsensusData = ConsensusData,
NextConsensus = NextConsensus,
Witness = Witness,
Transactions = Hashes.Select(p => cache[p].Transaction).ToArray()
Transactions = Hashes.Select(p => new ExecutedTransaction()
{
Transaction = cache[p].Transaction
// TODO: Get state
})
.ToArray()
};
}

Expand Down
30 changes: 15 additions & 15 deletions neo/Network/P2P/Payloads/Block.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
using Neo.Cryptography;
using Neo.IO;
using Neo.IO.Json;
using Neo.Ledger;
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Neo.Cryptography;
using Neo.IO;
using Neo.IO.Json;
using Neo.Ledger;

namespace Neo.Network.P2P.Payloads
{
public class Block : BlockBase, IInventory, IEquatable<Block>
{
public const int MaxTransactionsPerBlock = ushort.MaxValue;

public Transaction[] Transactions;
public ExecutedTransaction[] Transactions;

private Header _header = null;
public Header Header
Expand Down Expand Up @@ -53,26 +53,26 @@ public static Fixed8 CalculateNetFee(IEnumerable<Transaction> transactions)
public override void Deserialize(BinaryReader reader)
{
base.Deserialize(reader);
Transactions = new Transaction[reader.ReadVarInt(MaxTransactionsPerBlock)];
Transactions = new ExecutedTransaction[reader.ReadVarInt(MaxTransactionsPerBlock)];
if (Transactions.Length == 0) throw new FormatException();
HashSet<UInt256> hashes = new HashSet<UInt256>();
for (int i = 0; i < Transactions.Length; i++)
{
Transactions[i] = Transaction.DeserializeFrom(reader);
Transactions[i] = reader.ReadSerializable<ExecutedTransaction>();
if (i == 0)
{
if (Transactions[0].Type != TransactionType.MinerTransaction)
if (Transactions[0].Transaction.Type != TransactionType.MinerTransaction)
throw new FormatException();
}
else
{
if (Transactions[i].Type == TransactionType.MinerTransaction)
if (Transactions[i].Transaction.Type == TransactionType.MinerTransaction)
throw new FormatException();
}
if (!hashes.Add(Transactions[i].Hash))
if (!hashes.Add(Transactions[i].Transaction.Hash))
throw new FormatException();
}
if (MerkleTree.ComputeRoot(Transactions.Select(p => p.Hash).ToArray()) != MerkleRoot)
if (MerkleTree.ComputeRoot(Transactions.Select(p => p.Transaction.Hash).ToArray()) != MerkleRoot)
throw new FormatException();
}

Expand All @@ -95,7 +95,7 @@ public override int GetHashCode()

public void RebuildMerkleRoot()
{
MerkleRoot = MerkleTree.ComputeRoot(Transactions.Select(p => p.Hash).ToArray());
MerkleRoot = MerkleTree.ComputeRoot(Transactions.Select(p => p.Transaction.Hash).ToArray());
}

public override void Serialize(BinaryWriter writer)
Expand All @@ -107,7 +107,7 @@ public override void Serialize(BinaryWriter writer)
public override JObject ToJson()
{
JObject json = base.ToJson();
json["tx"] = Transactions.Select(p => p.ToJson()).ToArray();
json["tx"] = Transactions.Select(p => p.Transaction.ToJson()).ToArray();
return json;
}

Expand All @@ -123,7 +123,7 @@ public TrimmedBlock Trim()
ConsensusData = ConsensusData,
NextConsensus = NextConsensus,
Witness = Witness,
Hashes = Transactions.Select(p => p.Hash).ToArray()
Hashes = Transactions.Select(p => p.Transaction.Hash).ToArray()
};
}
}
Expand Down
26 changes: 26 additions & 0 deletions neo/Network/P2P/Payloads/ExecutedTransaction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.IO;
using Neo.IO;
using Neo.VM;

namespace Neo.Network.P2P.Payloads
{
public class ExecutedTransaction : ISerializable
{
public Transaction Transaction;
public VMState State;

public int Size => sizeof(VMState) + Transaction.Size;

public void Deserialize(BinaryReader reader)
{
Transaction = Transaction.DeserializeFrom(reader);
State = (VMState)reader.ReadByte();
}

public void Serialize(BinaryWriter writer)
{
((ISerializable)Transaction).Serialize(writer);
writer.Write((byte)State);
}
}
}
2 changes: 1 addition & 1 deletion neo/Network/P2P/Payloads/MerkleBlockPayload.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class MerkleBlockPayload : BlockBase

public static MerkleBlockPayload Create(Block block, BitArray flags)
{
MerkleTree tree = new MerkleTree(block.Transactions.Select(p => p.Hash).ToArray());
var tree = new MerkleTree(block.Transactions.Select(p => p.Transaction.Hash).ToArray());
tree.Trim(flags);
byte[] buffer = new byte[(flags.Length + 7) / 8];
flags.CopyTo(buffer, 0);
Expand Down
2 changes: 1 addition & 1 deletion neo/Network/P2P/ProtocolHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ private void OnGetDataMessageReceived(InvPayload payload)
}
else
{
BitArray flags = new BitArray(block.Transactions.Select(p => bloom_filter.Test(p)).ToArray());
var flags = new BitArray(block.Transactions.Select(p => bloom_filter.Test(p.Transaction)).ToArray());
Context.Parent.Tell(Message.Create("merkleblock", MerkleBlockPayload.Create(block, flags)));
}
}
Expand Down
2 changes: 1 addition & 1 deletion neo/SmartContract/ApplicationEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ public static ApplicationEngine Run(byte[] script, Snapshot snapshot,
InvocationScript = new byte[0],
VerificationScript = new byte[0]
},
Transactions = new Transaction[0]
Transactions = new ExecutedTransaction[0]
};
ApplicationEngine engine = new ApplicationEngine(TriggerType.Application, container, snapshot, extraGAS, testMode);
engine.LoadScript(script);
Expand Down
2 changes: 1 addition & 1 deletion neo/SmartContract/StandardService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ protected bool Block_GetTransaction(ExecutionEngine engine)
int index = (int)engine.CurrentContext.EvaluationStack.Pop().GetBigInteger();
if (block == null) return false;
if (index < 0 || index >= block.Transactions.Length) return false;
Transaction tx = block.Transactions[index];
var tx = block.Transactions[index].Transaction;
engine.CurrentContext.EvaluationStack.Push(StackItem.FromInterface(tx));
return true;
}
Expand Down
Loading