Skip to content

Commit

Permalink
Add List<Transaction>
Browse files Browse the repository at this point in the history
  • Loading branch information
chopin-fan committed Oct 18, 2024
1 parent 88d4e10 commit 9d9dd65
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AElf.Kernel.Blockchain.Domain;
using AElf.Kernel.FeatureDisable.Core;
using AElf.Kernel.SmartContract.Domain;
using AElf.Kernel.SmartContract.Infrastructure;
Expand All @@ -23,10 +24,12 @@ public class PlainTransactionExecutingService : IPlainTransactionExecutingServic
private readonly ISmartContractExecutiveService _smartContractExecutiveService;
private readonly ITransactionContextFactory _transactionContextFactory;
private readonly IFeatureDisableService _featureDisableService;
private readonly ITransactionManager _transactionManager;

public PlainTransactionExecutingService(ISmartContractExecutiveService smartContractExecutiveService,
IEnumerable<IPostExecutionPlugin> postPlugins, IEnumerable<IPreExecutionPlugin> prePlugins,
ITransactionContextFactory transactionContextFactory, IFeatureDisableService featureDisableService)
ITransactionContextFactory transactionContextFactory, IFeatureDisableService featureDisableService,
ITransactionManager transactionManager)
{
_smartContractExecutiveService = smartContractExecutiveService;
_transactionContextFactory = transactionContextFactory;
Expand All @@ -35,6 +38,7 @@ public PlainTransactionExecutingService(ISmartContractExecutiveService smartCont
_postPlugins = GetUniquePlugins(postPlugins);
Logger = NullLogger<PlainTransactionExecutingService>.Instance;
LocalEventBus = NullLocalEventBus.Instance;
_transactionManager = transactionManager;
}

public ILogger<PlainTransactionExecutingService> Logger { get; set; }
Expand Down Expand Up @@ -72,6 +76,8 @@ public async Task<List<ExecutionReturnSet>> ExecuteAsync(TransactionExecutingDto
cancellationToken), cancellationToken);

trace = await transactionExecutionTask.WithCancellation(cancellationToken);
// GetAllTrace(transactionTraces, trace);

}
catch (OperationCanceledException)
{
Expand All @@ -81,16 +87,42 @@ public async Task<List<ExecutionReturnSet>> ExecuteAsync(TransactionExecutingDto
continue;
}


if (!TryUpdateStateCache(trace, groupStateCache))
break;
List<TransactionTrace> traceList = new List<TransactionTrace>();
List<Transaction> inlineTxList = new List<Transaction>();
WrapTraceList(traceList, trace);
// WrapinlineTxList(inlineTxList, trace);
// foreach (var inlinetransaction in inlineTxList)
// {
// await _transactionManager.AddTransactionAsync(inlinetransaction);
// }

// if (!TryUpdateStateCache(trace, groupStateCache))
// break;
// #if DEBUG
// if (!string.IsNullOrEmpty(trace.Error)) Logger.LogInformation("{Error}", trace.Error);
// #endif
// var result = GetTransactionResult(trace, transactionExecutingDto.BlockHeader.Height);
//
// var returnSet = GetReturnSet(trace, result);
// returnSets.Add(returnSet);

int index = 1;
foreach (var transactionTrace in traceList)
{
Console.WriteLine("index="+ index+++" "+transactionTrace.TransactionId);

if (!TryUpdateStateCache(transactionTrace, groupStateCache))
break;
#if DEBUG
if (!string.IsNullOrEmpty(trace.Error)) Logger.LogInformation("{Error}", trace.Error);
if (!string.IsNullOrEmpty(transactionTrace.Error)) Logger.LogInformation("{Error}", transactionTrace.Error);
#endif
var result = GetTransactionResult(trace, transactionExecutingDto.BlockHeader.Height);
var result = GetTransactionResult(transactionTrace, transactionExecutingDto.BlockHeader.Height);

var returnSet = GetReturnSet(trace, result);
returnSets.Add(returnSet);
var returnSet = GetReturnSet(transactionTrace, result);
returnSets.Add(returnSet);

}

}

return returnSets;
Expand All @@ -102,6 +134,85 @@ public async Task<List<ExecutionReturnSet>> ExecuteAsync(TransactionExecutingDto
}
}

private void WrapinlineTxList(List<Transaction> inlineTxList, TransactionTrace trace)
{
// Create a stack to hold the traces for processing
Stack<TransactionTrace> stack = new Stack<TransactionTrace>();
stack.Push(trace);

// Process all traces in the stack
while (stack.Count > 0)
{
// Pop a trace from the stack
var currentTrace = stack.Pop();


foreach (var transaction in currentTrace.InlineTransactions.ToList())
{
if (transaction.IsInlineTxWithId)
{
inlineTxList.Add(transaction);
}
}

// If the current trace contains inline traces, add them to the stack
if (currentTrace.InlineTraces != null)
{
foreach (var inlineTrace in currentTrace.InlineTraces)
{
stack.Push(inlineTrace);
}
}
}
}

private List<TransactionTrace> WrapTraceList(List<TransactionTrace> traceList, TransactionTrace trace)
{
// Create a stack to hold the traces for processing
Stack<TransactionTrace> stack = new Stack<TransactionTrace>();
stack.Push(trace);

// Process all traces in the stack
while (stack.Count > 0)
{
// Pop a trace from the stack
var currentTrace = stack.Pop();

// Add the current trace to the list
if (currentTrace.IsInlineTransaction)
{
traceList.Add(currentTrace);
}

// If the current trace contains inline traces, add them to the stack
if (currentTrace.InlineTraces != null)
{
foreach (var inlineTrace in currentTrace.InlineTraces)
{
stack.Push(inlineTrace);
}
}
}

return traceList;
}


private void GetAllTrace(List<TransactionTrace> transactionTraces, TransactionTrace transactionTrace)
{
if (transactionTrace == null || transactionTrace.InlineTraces.Count == 0)
{
return;
}

transactionTraces.Add(transactionTrace);

foreach (var inlineTrace in transactionTrace.InlineTraces)
{
GetAllTrace(transactionTraces, inlineTrace);
}
}

private static bool TryUpdateStateCache(TransactionTrace trace, TieredStateCache groupStateCache)
{
if (trace == null)
Expand Down Expand Up @@ -221,8 +332,13 @@ private async Task ExecuteInlineTransactions(int depth, Timestamp currentBlockTi
{
var trace = txContext.Trace;
internalStateCache.Update(txContext.Trace.GetStateSets());
int index = 0;
foreach (var inlineTx in txContext.Trace.InlineTransactions)
{
if (txContext.IsInlineTransaction)
{
AutoGenerateInlineTxId(inlineTx,originTransactionId,index);
}
var singleTxExecutingDto = new SingleTransactionExecutingDto
{
Depth = depth + 1,
Expand All @@ -237,6 +353,11 @@ private async Task ExecuteInlineTransactions(int depth, Timestamp currentBlockTi

if (inlineTrace == null)
break;

// if (txContext.IsInlineTransaction)
// {
// inlineTrace.IsInlineTransaction = true;
// }
trace.InlineTraces.Add(inlineTrace);
if (!inlineTrace.IsSuccessful())
// Already failed, no need to execute remaining inline transactions
Expand All @@ -246,6 +367,11 @@ private async Task ExecuteInlineTransactions(int depth, Timestamp currentBlockTi
}
}

private void AutoGenerateInlineTxId(Transaction inlineTx, Hash originTransactionId, int index)
{
inlineTx.SetHash(HashHelper.XorAndCompute(originTransactionId, HashHelper.ComputeFrom(index)));
}

private async Task<bool> ExecutePluginOnPreTransactionStageAsync(IExecutive executive,
ITransactionContext txContext,
Timestamp currentBlockTime,
Expand Down
27 changes: 26 additions & 1 deletion src/AElf.Kernel.SmartContract/HostSmartContractBridgeContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,19 @@ public void SendInline(Address toAddress, string methodName, ByteString args)
Params = args
});
}

public void SendInlineWithTransactionId(Address toAddress, string methodName, ByteString args)
{
// TransactionContext.IsInlineTransaction = true;
TransactionContext.Trace.InlineTransactions.Add(new Transaction
{
IsInlineTxWithId = true,
From = Self,
To = toAddress,
MethodName = methodName,
Params = args
});
}

public void SendVirtualInline(Hash fromVirtualAddress, Address toAddress, string methodName,
ByteString args)
Expand All @@ -247,7 +260,19 @@ public void SendVirtualInline(Hash fromVirtualAddress, Address toAddress, string
Params = args
});
}


public void SendVirtualInlineTransactionId(Hash fromVirtualAddress, Address toAddress, string methodName, ByteString args)
{
TransactionContext.Trace.InlineTransactions.Add(new Transaction
{
IsInlineTxWithId = true,
From = ConvertVirtualAddressToContractAddress(fromVirtualAddress, Self),
To = toAddress,
MethodName = methodName,
Params = args
});
}

public void SendVirtualInline(Hash fromVirtualAddress, Address toAddress, string methodName,
ByteString args, bool logTransaction)
{
Expand Down
2 changes: 2 additions & 0 deletions src/AElf.Kernel.SmartContract/ITransactionContext.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Collections.Generic;
using AElf.Types;
using Google.Protobuf.WellKnownTypes;

Expand All @@ -16,4 +17,5 @@ public interface ITransactionContext
Transaction Transaction { get; set; }
TransactionTrace Trace { get; set; }
IStateCache StateCache { get; set; }
bool IsInlineTransaction { get; set; }
}
1 change: 1 addition & 0 deletions src/AElf.Kernel.SmartContract/TransactionContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ public class TransactionContext : ITransactionContext
public Transaction Transaction { get; set; }
public TransactionTrace Trace { get; set; }
public IStateCache StateCache { get; set; }
public bool IsInlineTransaction { get; set; }
}
2 changes: 2 additions & 0 deletions src/AElf.Kernel.Types/Transaction/TransactionTrace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public partial class TransactionTrace
{
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }

public bool IsInlineTransaction { get; set; }

public IEnumerable<LogEvent> FlattenedLogs
{
Expand Down
2 changes: 1 addition & 1 deletion src/AElf.Sdk.CSharp/CSharpSmartContractContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ public T Call<T>(Address fromAddress, Address toAddress, string methodName, Byte
public void SendInline(Address toAddress, string methodName, ByteString args)
{
SmartContractBridgeContextImplementation.SendInline(toAddress, methodName, args);
}
}

/// <summary>
/// Sends a virtual inline transaction to another contract.
Expand Down
6 changes: 6 additions & 0 deletions src/AElf.Sdk.CSharp/SmartContractBridgeContextExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ public static void SendInline(this CSharpSmartContractContext context, Address t
{
context.SendInline(toAddress, methodName, ConvertToByteString(message));
}

public static void SendInlineWithTransactionId(this CSharpSmartContractContext context, Address toAddress, string methodName,
IMessage message)
{
context.SendInline(toAddress, methodName, ConvertToByteString(message));
}

/// <summary>
/// Sends a virtual inline transaction to another contract.
Expand Down
8 changes: 7 additions & 1 deletion src/AElf.Types/Types/Transaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@

namespace AElf.Types
{

public partial class Transaction
{
private Hash _transactionId;

public bool IsInlineTxWithId;

public Hash GetHash()
{
Expand All @@ -16,6 +17,11 @@ public Hash GetHash()
return _transactionId;
}

public void SetHash(Hash transactionId)
{
_transactionId = transactionId;
}

public bool VerifyFields()
{
if (To == null || From == null)
Expand Down

0 comments on commit 9d9dd65

Please sign in to comment.