-
Notifications
You must be signed in to change notification settings - Fork 261
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3384 from AElfProject/fix/code-check-exception
Fix code check failure in parallel
- Loading branch information
Showing
22 changed files
with
617 additions
and
351 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
namespace AElf.Kernel.CodeCheck.Application; | ||
|
||
public class CodeCheckJob | ||
{ | ||
public Hash BlockHash { get; set; } | ||
public long BlockHeight { get; set; } | ||
public byte[] ContractCode { get; set; } | ||
public int ContractCategory { get; set; } | ||
public bool IsSystemContract { get; set; } | ||
public bool IsUserContract { get; set; } | ||
public Hash CodeCheckProposalId { get; set; } | ||
public Hash ProposedContractInputHash { get; set; } | ||
public long BucketIndex { get; set; } | ||
} |
123 changes: 123 additions & 0 deletions
123
src/AElf.Kernel.CodeCheck/Application/CodeCheckJobProcessor.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Runtime.Loader; | ||
using System.Threading.Tasks.Dataflow; | ||
using AElf.Kernel.Proposal.Application; | ||
|
||
namespace AElf.Kernel.CodeCheck.Application; | ||
|
||
public interface ICodeCheckJobProcessor | ||
{ | ||
Task<bool> SendAsync(CodeCheckJob job); | ||
Task CompleteAsync(); | ||
} | ||
|
||
public class CodeCheckJobProcessor : ICodeCheckJobProcessor, ISingletonDependency | ||
{ | ||
private readonly TransformBlock<CodeCheckJob, CodeCheckJob> _codeCheckTransformBlock; | ||
private List<ActionBlock<CodeCheckJob>> _codeCheckProcessesJobTransformBlock; | ||
private readonly CodeCheckOptions _codeCheckOptions; | ||
private readonly ICheckedCodeHashProvider _checkedCodeHashProvider; | ||
private readonly ICodeCheckService _codeCheckService; | ||
private readonly IProposalService _proposalService; | ||
private readonly ICodeCheckProposalService _codeCheckProposalService; | ||
|
||
public ILogger<CodeCheckJobProcessor> Logger { get; set; } | ||
|
||
public CodeCheckJobProcessor(IOptionsSnapshot<CodeCheckOptions> codeCheckOptions, | ||
ICheckedCodeHashProvider checkedCodeHashProvider, IProposalService proposalService, | ||
ICodeCheckService codeCheckService, ICodeCheckProposalService codeCheckProposalService) | ||
{ | ||
_checkedCodeHashProvider = checkedCodeHashProvider; | ||
_proposalService = proposalService; | ||
_codeCheckService = codeCheckService; | ||
_codeCheckProposalService = codeCheckProposalService; | ||
_codeCheckOptions = codeCheckOptions.Value; | ||
_codeCheckTransformBlock = CreateCodeCheckBufferBlock(); | ||
|
||
Logger = NullLogger<CodeCheckJobProcessor>.Instance; | ||
} | ||
|
||
public async Task<bool> SendAsync(CodeCheckJob job) | ||
{ | ||
return await _codeCheckTransformBlock.SendAsync(job); | ||
} | ||
|
||
public async Task CompleteAsync() | ||
{ | ||
_codeCheckTransformBlock.Complete(); | ||
await Task.WhenAll(_codeCheckProcessesJobTransformBlock.Select(o => o.Completion)); | ||
} | ||
|
||
private TransformBlock<CodeCheckJob, CodeCheckJob> CreateCodeCheckBufferBlock() | ||
{ | ||
var linkOptions = new DataflowLinkOptions { PropagateCompletion = true }; | ||
|
||
var updateBucketIndexTransformBlock = new TransformBlock<CodeCheckJob, CodeCheckJob>(UpdateBucketIndex, | ||
new ExecutionDataflowBlockOptions | ||
{ | ||
BoundedCapacity = Math.Max(_codeCheckOptions.MaxBoundedCapacity, 1), | ||
MaxDegreeOfParallelism = _codeCheckOptions.MaxDegreeOfParallelism | ||
}); | ||
|
||
_codeCheckProcessesJobTransformBlock = new List<ActionBlock<CodeCheckJob>>(); | ||
for (var i = 0; i < _codeCheckOptions.MaxDegreeOfParallelism; i++) | ||
{ | ||
var processCodeCheckJobTransformBlock = new ActionBlock<CodeCheckJob>( | ||
async codeCheckJob => await ProcessCodeCheckJobAsync(codeCheckJob), | ||
new ExecutionDataflowBlockOptions | ||
{ | ||
BoundedCapacity = Math.Max(_codeCheckOptions.MaxBoundedCapacity, 1), | ||
EnsureOrdered = false | ||
}); | ||
var index = i; | ||
updateBucketIndexTransformBlock.LinkTo(processCodeCheckJobTransformBlock, linkOptions, | ||
codeCheckJob => codeCheckJob.BucketIndex == index); | ||
_codeCheckProcessesJobTransformBlock.Add(processCodeCheckJobTransformBlock); | ||
} | ||
|
||
return updateBucketIndexTransformBlock; | ||
} | ||
|
||
private async Task ProcessCodeCheckJobAsync(CodeCheckJob job) | ||
{ | ||
var codeCheckResult = await _codeCheckService.PerformCodeCheckAsync(job.ContractCode, job.BlockHash, | ||
job.BlockHeight, job.ContractCategory, job.IsSystemContract, job.IsUserContract); | ||
|
||
var codeHash = HashHelper.ComputeFrom(job.ContractCode); | ||
Logger.LogInformation("Code check result: {codeCheckResult}, code hash: {codeHash}", codeCheckResult, | ||
codeHash.ToHex()); | ||
|
||
if (!codeCheckResult) | ||
return; | ||
|
||
if (job.IsUserContract) | ||
{ | ||
_codeCheckProposalService.AddReleasableProposal(job.CodeCheckProposalId, job.ProposedContractInputHash, | ||
job.BlockHeight); | ||
} | ||
|
||
// Cache proposal id to generate system approval transaction later | ||
_proposalService.AddNotApprovedProposal(job.CodeCheckProposalId, job.BlockHeight); | ||
|
||
await _checkedCodeHashProvider.AddCodeHashAsync(new BlockIndex | ||
{ | ||
BlockHash = job.BlockHash, | ||
BlockHeight = job.BlockHeight | ||
}, codeHash); | ||
} | ||
|
||
private CodeCheckJob UpdateBucketIndex(CodeCheckJob job) | ||
{ | ||
var assemblyLoadContext = new AssemblyLoadContext(null, true); | ||
var assembly = assemblyLoadContext.LoadFromStream(new MemoryStream(job.ContractCode)); | ||
|
||
job.BucketIndex = | ||
Math.Abs(HashHelper.ComputeFrom(assembly.GetName().Name).ToInt64() % _codeCheckOptions.MaxDegreeOfParallelism); | ||
assemblyLoadContext.Unload(); | ||
|
||
return job; | ||
} | ||
} |
93 changes: 0 additions & 93 deletions
93
src/AElf.Kernel.CodeCheck/Application/CodeCheckTransactionValidationProvider.cs
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
using System.Runtime.CompilerServices; | ||
|
||
[assembly: InternalsVisibleTo("AElf.Kernel.CodeCheck.Tests")] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.