private BoundBlock BuildBlock(BoundStatement node) { var block = node as BoundBlock; if (block != null) return block; var builder = new BlockBuilder(this); builder.Add(node); return builder.BuildBlock(node.Location); }
private BoundBlock BuildBlock(SyntaxNode syntax, SourceLocation location) { IEnumerable<SyntaxNode> items; var block = syntax as BlockSyntax; if (block != null) items = block.Statements; else items = new[] { syntax }; var builder = new BlockBuilder(this); foreach (var item in items) { var node = item.Accept(this); var statement = node as BoundStatement ?? new BoundExpressionStatement((BoundExpression)node, GetLocation(item)); builder.Add(statement); } return builder.BuildBlock(location ?? SourceLocation.Missing); }
private MSAst.Expression ReduceWorker(bool optimizeDynamicConvert) { MSAst.Expression result; if (_tests.Length > 100) { // generate: // if(x) { // body // goto end // } else { // } // elseBody // end: // // to avoid deeply recursive trees which can stack overflow. BlockBuilder builder = new BlockBuilder(); var label = Ast.Label(); for (int i = 0; i < _tests.Length; i++) { IfStatementTest ist = _tests[i]; builder.Add( Ast.Condition( optimizeDynamicConvert ? TransformAndDynamicConvert(ist.Test, typeof(bool)) : GlobalParent.Convert(typeof(bool), Microsoft.Scripting.Actions.ConversionResultKind.ExplicitCast, ist.Test), Ast.Block( TransformMaybeSingleLineSuite(ist.Body, GlobalParent.IndexToLocation(ist.Test.StartIndex)), Ast.Goto(label) ), Utils.Empty() ) ); } if (ElseStatement != null) { builder.Add(ElseStatement); } builder.Add(Ast.Label(label)); result = builder.ToExpression(); } else { // Now build from the inside out if (ElseStatement != null) { result = ElseStatement; } else { result = AstUtils.Empty(); } int i = _tests.Length; while (i-- > 0) { IfStatementTest ist = _tests[i]; result = GlobalParent.AddDebugInfoAndVoid( Ast.Condition( optimizeDynamicConvert ? TransformAndDynamicConvert(ist.Test, typeof(bool)) : GlobalParent.Convert(typeof(bool), Microsoft.Scripting.Actions.ConversionResultKind.ExplicitCast, ist.Test), TransformMaybeSingleLineSuite(ist.Body, GlobalParent.IndexToLocation(ist.Test.StartIndex)), result ), new SourceSpan(GlobalParent.IndexToLocation(ist.StartIndex), GlobalParent.IndexToLocation(ist.HeaderIndex)) ); } } return(result); }
public void ReorgChain_AfterInitialRewind_ChainA_Extension_MinerC_Disconnects() { using (var builder = NodeBuilder.Create(this)) { var minerA = builder.CreateStratisPosNode(new StratisRegTest()).OverrideDateTimeProvider().WithDummyWallet(); var minerB = builder.CreateStratisPosNode(new StratisRegTest()).OverrideDateTimeProvider().NoValidation().WithDummyWallet(); var minerC = builder.CreateStratisPosNode(new StratisRegTest()).OverrideDateTimeProvider().WithDummyWallet(); // Configure the interceptor to disconnect a node after a certain block has been disconnected (rewound). bool interceptor(ChainedHeaderBlock chainedHeaderBlock) { if (chainedHeaderBlock.ChainedHeader.Previous.Height == 5) { // Ensure that minerA's tip has rewound to 5. TestHelper.WaitLoop(() => TestHelper.IsNodeSyncedAtHeight(minerA, 5)); TestHelper.Disconnect(minerA, minerC); return(true); } return(false); } minerA.BlockDisconnectInterceptor(interceptor); // Start the nodes. minerA.Start(); minerB.Start(); minerC.Start(); // MinerA mines 5 blocks. TestHelper.MineBlocks(minerA, 5); // MinerB and MinerC syncs with MinerA. TestHelper.ConnectAndSync(minerA, minerB, minerC); // Disconnect MinerB from MinerA so that is can mine on its own and create a fork. TestHelper.Disconnect(minerA, minerB); // MinerA continues to mine to height 9. TestHelper.MineBlocks(minerA, 4); TestHelper.WaitLoop(() => minerA.FullNode.ConsensusManager().Tip.Height == 9); TestHelper.WaitLoop(() => minerB.FullNode.ConsensusManager().Tip.Height == 5); TestHelper.WaitLoop(() => minerC.FullNode.ConsensusManager().Tip.Height == 9); // MinerB mines 5 more blocks: // Block 6,7,9,10 = valid // Block 8 = invalid Assert.False(TestHelper.IsNodeConnected(minerB)); TestHelper.BuildBlocks.OnNode(minerB).Amount(5).Invalid(8, (node, block) => BlockBuilder.InvalidCoinbaseReward(node, block)).BuildAsync(); // Reconnect MinerA to MinerB. TestHelper.Connect(minerA, minerB); // MinerC should be disconnected from MinerA. TestHelper.WaitLoop(() => !TestHelper.IsNodeConnectedTo(minerA, minerC)); // This will cause the reorg chain to fail at block 8 and roll back any changes. TestHelper.WaitLoop(() => TestHelper.IsNodeSyncedAtHeight(minerA, 9)); TestHelper.WaitLoop(() => TestHelper.IsNodeSyncedAtHeight(minerC, 9)); } }
private static Block RebuildChunkGenerators(Block block, bool isBound) { var builder = new BlockBuilder(block); // Don't want to rebuild unbound dynamic attributes. They need to run through the conditional attribute // removal system at runtime. A conditional attribute at the parse tree rewriting level is defined by // having at least 1 child with a DynamicAttributeBlockChunkGenerator. if (!isBound && block.Children.Any( child => child.IsBlock && ((Block)child).ChunkGenerator is DynamicAttributeBlockChunkGenerator)) { // The parent chunk generator must be removed because it's normally responsible for conditionally // generating the attribute prefix (class=") and suffix ("). The prefix and suffix concepts aren't // applicable for the TagHelper use case since the attributes are put into a dictionary like object as // name value pairs. builder.ChunkGenerator = ParentChunkGenerator.Null; return(builder.Build()); } var isDynamic = builder.ChunkGenerator is DynamicAttributeBlockChunkGenerator; // We don't want any attribute specific logic here, null out the block chunk generator. if (isDynamic || builder.ChunkGenerator is AttributeBlockChunkGenerator) { builder.ChunkGenerator = ParentChunkGenerator.Null; } for (var i = 0; i < builder.Children.Count; i++) { var child = builder.Children[i]; if (child.IsBlock) { // The child is a block, recurse down into the block to rebuild its children builder.Children[i] = RebuildChunkGenerators((Block)child, isBound); } else { var childSpan = (Span)child; ISpanChunkGenerator newChunkGenerator = null; var literalGenerator = childSpan.ChunkGenerator as LiteralAttributeChunkGenerator; if (literalGenerator != null) { if (literalGenerator.ValueGenerator == null || literalGenerator.ValueGenerator.Value == null) { newChunkGenerator = new MarkupChunkGenerator(); } else { newChunkGenerator = literalGenerator.ValueGenerator.Value; } } else if (isDynamic && childSpan.ChunkGenerator == SpanChunkGenerator.Null) { // Usually the dynamic chunk generator handles creating the null chunk generators underneath // it. This doesn't make sense in terms of tag helpers though, we need to change null code // generators to markup chunk generators. newChunkGenerator = new MarkupChunkGenerator(); } // If we have a new chunk generator we'll need to re-build the child if (newChunkGenerator != null) { var childSpanBuilder = new SpanBuilder(childSpan) { ChunkGenerator = newChunkGenerator }; builder.Children[i] = childSpanBuilder.Build(); } } } return(builder.Build()); }
public async Task ReorgChain_AfterInitialRewind_ChainA_Extension_MinerC_DisconnectsAsync() { using (var builder = NodeBuilder.Create(this)) { var network = new BitcoinRegTest(); var minerA = builder.CreateStratisPowNode(network).WithDummyWallet().WithReadyBlockchainData(ReadyBlockchain.BitcoinRegTest10Miner); var minerB = builder.CreateStratisPowNode(network).NoValidation().WithDummyWallet(); var syncer = builder.CreateStratisPowNode(network).WithDummyWallet(); bool minerADisconnectedFromSyncer = false; // Configure the interceptor to disconnect a node after a certain block has been disconnected (rewound). void interceptor(ChainedHeaderBlock chainedHeaderBlock) { if (minerADisconnectedFromSyncer) { return; } if (chainedHeaderBlock.ChainedHeader.Previous.Height == 10) { // Ensure that minerA's tip has rewound to 10. TestHelper.WaitLoop(() => TestHelper.IsNodeSyncedAtHeight(minerA, 10)); TestHelper.Disconnect(minerA, syncer); minerADisconnectedFromSyncer = true; return; } } // Start the nodes. minerA.Start(); minerB.Start(); syncer.Start(); minerA.SetDisconnectInterceptor(interceptor); // minerB and syncer syncs with minerA. TestHelper.ConnectAndSync(minerA, minerB, syncer); // Disconnect minerB from miner so that it can mine on its own and create a fork. TestHelper.Disconnect(minerA, minerB); // MinerA continues to mine to height 14. TestHelper.MineBlocks(minerA, 4); TestHelper.WaitLoop(() => minerA.FullNode.ConsensusManager().Tip.Height == 14); TestHelper.WaitLoop(() => minerB.FullNode.ConsensusManager().Tip.Height == 10); TestHelper.WaitLoop(() => syncer.FullNode.ConsensusManager().Tip.Height == 14); // minerB mines 5 more blocks: // Block 6,7,9,10 = valid // Block 8 = invalid Assert.False(TestHelper.IsNodeConnected(minerB)); await TestHelper.BuildBlocks.OnNode(minerB).Amount(5).Invalid(13, (node, block) => BlockBuilder.InvalidCoinbaseReward(node, block)).BuildAsync(); // Reconnect minerA to minerB. TestHelper.ConnectNoCheck(minerA, minerB); // minerB should be disconnected from minerA. TestHelper.WaitLoop(() => !TestHelper.IsNodeConnectedTo(minerA, minerB)); // syncer should be disconnected from minerA (via interceptor). TestHelper.WaitLoop(() => !TestHelper.IsNodeConnectedTo(minerA, syncer)); // The reorg will fail at block 8 and roll back any changes. TestHelper.WaitLoop(() => TestHelper.IsNodeSyncedAtHeight(minerA, 14)); TestHelper.WaitLoop(() => TestHelper.IsNodeSyncedAtHeight(minerB, 15)); TestHelper.WaitLoop(() => TestHelper.IsNodeSyncedAtHeight(syncer, 14)); } }
private void MinifyMarkup(BlockBuilder block) { var codeGenerator = new MarkupCodeGenerator(); var previousIsWhiteSpace = true; var previousTokenEndsWithBlockElement = true; var insideScript = false; for (int i = 0; i < block.Children.Count; i++) { var node = block.Children[i]; var span = node as Span; if (span == null) { // When we have a dynamic markup, we can't know if the last char will be whitespace // => to make it work in all cases, we won't minifiy whitespace just after code. previousIsWhiteSpace = false; previousTokenEndsWithBlockElement = false; continue; } // There may be several HTML tokens just one after the other. // => we concatenate everything in a single token to minify everyting in a single scan // (we is better for Javascript minification). var sb = new StringBuilder(); sb.Append(span.Content); if (i < block.Children.Count - 1) { var markup = block.Children[i + 1] as Span; while ((markup != null) && (markup.Kind == SpanKind.Markup) && ((markup.Next == null) || ((markup.Next != null) && ((markup.Next.Kind == SpanKind.Markup) || ((markup.Next.Kind != SpanKind.Markup) && !markup.Content.EndsWith("\"")))))) { block.Children.RemoveAt(i + 1); sb.Append(markup.Content); markup = i + 1 < block.Children.Count ? block.Children[i + 1] as Span : null; } } var content = sb.ToString(); if (string.IsNullOrEmpty(content)) { // Nothing to minify block.Children.RemoveAt(i); continue; } content = _minifier.Minify(content, previousIsWhiteSpace, previousTokenEndsWithBlockElement, insideScript); _minifier.AnalyseContent(content, ref previousIsWhiteSpace, ref previousTokenEndsWithBlockElement, ref insideScript); // We replace the content with the minified markup // and then let the CSharp/VB generator do their jobs. var builder = new SpanBuilder() { CodeGenerator = codeGenerator, EditHandler = span.EditHandler, Kind = span.Kind, Start = span.Start }; var symbol = new MarkupSymbol() { Content = content }; builder.Accept(symbol); span.ReplaceWith(builder); } }
private static TryParseResult TryParseBlock( string tagName, Block block, IEnumerable <TagHelperDescriptor> descriptors, ErrorSink errorSink) { // TODO: Accept more than just spans: https://github.com/aspnet/Razor/issues/96. // The first child will only ever NOT be a Span if a user is doing something like: // <input @checked /> var childSpan = block.Children.First() as Span; if (childSpan == null || childSpan.Kind != SpanKind.Markup) { errorSink.OnError(block.Children.First().Start, RazorResources.FormatTagHelpers_CannotHaveCSharpInTagDeclaration(tagName)); return(null); } var builder = new BlockBuilder(block); // If there's only 1 child it means that it's plain text inside of the attribute. // i.e. <div class="plain text in attribute"> if (builder.Children.Count == 1) { return(TryParseSpan(childSpan, descriptors, errorSink)); } var textSymbol = childSpan.Symbols.FirstHtmlSymbolAs(HtmlSymbolType.Text); var name = textSymbol != null ? textSymbol.Content : null; if (name == null) { errorSink.OnError(childSpan.Start, RazorResources.FormatTagHelpers_AttributesMustHaveAName(tagName)); return(null); } // Have a name now. Able to determine correct isBoundNonStringAttribute value. var result = CreateTryParseResult(name, descriptors); // Remove first child i.e. foo=" builder.Children.RemoveAt(0); // Grabbing last child to check if the attribute value is quoted. var endNode = block.Children.Last(); if (!endNode.IsBlock) { var endSpan = (Span)endNode; // In some malformed cases e.g. <p bar="false', the last Span (false' in the ex.) may contain more // than a single HTML symbol. Do not ignore those other symbols. var symbolCount = endSpan.Symbols.Count(); var endSymbol = symbolCount == 1 ? (HtmlSymbol)endSpan.Symbols.First() : null; // Checking to see if it's a quoted attribute, if so we should remove end quote if (endSymbol != null && IsQuote(endSymbol)) { builder.Children.RemoveAt(builder.Children.Count - 1); } } // We need to rebuild the chunk generators of the builder and its children (this is needed to // ensure we don't do special attribute chunk generation since this is a tag helper). block = RebuildChunkGenerators(builder.Build()); // If there's only 1 child at this point its value could be a simple markup span (treated differently than // block level elements for attributes). if (block.Children.Count() == 1) { var child = block.Children.First() as Span; if (child != null) { // After pulling apart the block we just have a value span. var spanBuilder = new SpanBuilder(child); result.AttributeValueNode = CreateMarkupAttribute(spanBuilder, result.IsBoundNonStringAttribute); return(result); } } result.AttributeValueNode = ConvertToMarkupAttributeBlock(block, result.IsBoundNonStringAttribute); return(result); }
// // rescue stmts ... if (StandardError === $!) { stmts; } // rescue <types> stmts ... temp1 = type1; ...; if (<temp1> === $! || ...) { stmts; } // rescue <types> => <lvalue> stmts ... temp1 = type1; ...; if (<temp1> === $! || ...) { <lvalue> = $!; stmts; } // /*!*/ internal IfStatementTest Transform(AstGenerator/*!*/ gen, ResultOperation resultOperation) { Assert.NotNull(gen); MSA.Expression condition; if (_types.Length != 0) { var comparisonSiteStorage = Ast.Constant(new BinaryOpStorage(gen.Context)); if (_types.Length == 1) { condition = MakeCompareException(gen, comparisonSiteStorage, _types[0].TransformRead(gen), _types[0] is SplattedArgument); } else { // forall{i}: <temps[i]> = evaluate type[i] var temps = new MSA.Expression[_types.Length]; var exprs = new BlockBuilder(); for (int i = 0; i < _types.Length; i++) { var t = _types[i].TransformRead(gen); var tmp = gen.CurrentScope.DefineHiddenVariable("#type_" + i, t.Type); temps[i] = tmp; exprs.Add(Ast.Assign(tmp, t)); } // CompareException(<temps[0]>) || ... CompareException(<temps[n]>) || CompareSplattedExceptions(<splatTypes>) condition = MakeCompareException(gen, comparisonSiteStorage, temps[0], _types[0] is SplattedArgument); for (int i = 1; i < _types.Length; i++) { condition = Ast.OrElse(condition, MakeCompareException(gen, comparisonSiteStorage, temps[i], _types[i] is SplattedArgument)); } // (temps[0] = type[0], ..., temps[n] == type[n], condition) exprs.Add(condition); condition = exprs; } } else { condition = Methods.CompareDefaultException.OpCall(gen.CurrentScopeVariable); } return AstUtils.IfCondition(condition, gen.TransformStatements( // <lvalue> = e; (_target != null) ? _target.TransformWrite(gen, Methods.GetCurrentException.OpCall(gen.CurrentScopeVariable)) : null, // body: _statements, resultOperation ) ); }
public void ReorgChain_FailsPartialValidation_Nodes_Disconnected() { using (var builder = NodeBuilder.Create(this)) { var stratisNoValidationRulesNetwork = new StratisRegTestNoValidationRules(); var minerA = builder.CreateStratisPosNode(this.posNetwork).WithDummyWallet().Start(); var minerB = builder.CreateStratisPosNode(stratisNoValidationRulesNetwork).NoValidation().WithDummyWallet().Start(); // MinerA mines 5 blocks TestHelper.MineBlocks(minerA, 5); // MinerB syncs with MinerA TestHelper.ConnectAndSync(minerB, minerA); // Disconnect minerA from miner B TestHelper.Disconnect(minerB, minerA); // Miner A continues to mine to height 9 TestHelper.MineBlocks(minerA, 4); TestHelper.WaitLoop(() => minerA.FullNode.ConsensusManager().Tip.Height == 9); // MinerB mines 5 more blocks: // Block 6,7,9,10 = valid // Block 8 = invalid TestHelper.BuildBlocks.OnNode(minerB).Amount(5).Invalid(8, (coreNode, block) => BlockBuilder.InvalidDuplicateCoinbase(coreNode, block)).BuildAsync(); // Reconnect minerA to minerB. // This will cause the reorg chain to fail at block 8 and roll back any changes. TestHelper.Connect(minerA, minerB); TestHelper.WaitLoop(() => minerA.FullNode.ConsensusManager().Tip.Height == 9); TestHelper.WaitLoop(() => minerB.FullNode.ConsensusManager().Tip.Height == 10); } }
private BoundIf BuildSetWithScope(BlockBuilder builder, WithScope withScope, IIdentifier fallback, BoundTemporary value) { var withLocal = builder.CreateTemporary(); builder.Add(new BoundSetVariable( withLocal, new BoundGetVariable(_withIdentifiers[withScope.Identifier]), SourceLocation.Missing )); var setter = new BoundSetMember( new BoundGetVariable(withLocal), BoundConstant.Create(fallback.Name), new BoundGetVariable(value), SourceLocation.Missing ); BoundBlock @else; if (withScope.Parent == null) { @else = BuildBlock(BuildSet( fallback, new BoundGetVariable(value) )); } else { @else = BuildBlock(BuildSetWithScope( builder, withScope.Parent, fallback, value )); } return new BoundIf( new BoundHasMember( new BoundGetVariable(withLocal), fallback.Name ), BuildBlock(setter), @else, SourceLocation.Missing ); }
private BoundStatement BuildSet(IIdentifier identifier, BoundExpression value) { switch (identifier.Type) { case IdentifierType.Parameter: return new BoundSetVariable( _scope.GetArgument(identifier), value, SourceLocation.Missing ); case IdentifierType.Scoped: var builder = new BlockBuilder(this); var valueTemporary = builder.CreateTemporary(); builder.Add(new BoundSetVariable( valueTemporary, value, SourceLocation.Missing )); builder.Add(BuildSetWithScope(builder, identifier.WithScope, identifier.Fallback, valueTemporary)); return builder.BuildBlock(SourceLocation.Missing); case IdentifierType.Local: case IdentifierType.Global: if (identifier.Type == IdentifierType.Global) _scope.IsGlobalScopeReferenced = true; if (identifier.Closure == null) return new BoundSetVariable(_scope.GetLocal(identifier), value, SourceLocation.Missing); return new BoundSetVariable( _scope.GetClosureField(identifier), value, SourceLocation.Missing ); /* // These are handled upstream. case IdentifierType.This: case IdentifierType.Null: case IdentifierType.Undefined: case IdentifierType.Arguments: */ default: throw new InvalidOperationException("Cannot find variable of argument"); } }
private BoundIf BuildGetWithScope(BlockBuilder builder, WithScope withScope, IIdentifier fallback, BoundTemporary result, BoundTemporary withTarget) { var withLocal = builder.CreateTemporary(); builder.Add(new BoundSetVariable( withLocal, new BoundGetVariable(_withIdentifiers[withScope.Identifier]), SourceLocation.Missing )); var getter = new BlockBuilder(this); if (withTarget != null) { getter.Add(new BoundSetVariable( withTarget, new BoundGetVariable(withLocal), SourceLocation.Missing )); } getter.Add(new BoundSetVariable( result, BuildGetMember( new BoundGetVariable(withLocal), BoundConstant.Create(fallback.Name) ), SourceLocation.Missing )); BoundBlock @else; if (withScope.Parent == null) { @else = BuildBlock(new BoundSetVariable( result, BuildGet( fallback, null ), SourceLocation.Missing )); } else { @else = BuildBlock(BuildGetWithScope( builder, withScope.Parent, fallback, result, withTarget )); } return new BoundIf( new BoundHasMember( new BoundGetVariable(withLocal), fallback.Name ), getter.BuildBlock(SourceLocation.Missing), @else, SourceLocation.Missing ); }
private BoundExpression BuildGet(IIdentifier identifier, BoundTemporary withTarget) { switch (identifier.Type) { case IdentifierType.Null: return new BoundGetVariable(BoundMagicVariable.Null); case IdentifierType.Undefined: return new BoundGetVariable(BoundMagicVariable.Undefined); case IdentifierType.This: _scope.IsThisReferenced = true; return new BoundGetVariable(BoundMagicVariable.This); case IdentifierType.Arguments: _scope.IsArgumentsReferenced = true; return new BoundGetVariable(BoundMagicVariable.Arguments); case IdentifierType.Parameter: return new BoundGetVariable(_scope.GetArgument(identifier)); case IdentifierType.Scoped: var builder = new BlockBuilder(this); var result = builder.CreateTemporary(); builder.Add( BuildGetWithScope(builder, identifier.WithScope, identifier.Fallback, result, withTarget) ); return builder.BuildExpression(result, SourceLocation.Missing); case IdentifierType.Local: case IdentifierType.Global: if (identifier.Closure != null) return new BoundGetVariable(_scope.GetClosureField(identifier)); return new BoundGetVariable(_scope.GetLocal(identifier)); default: throw new InvalidOperationException("Cannot find variable of argument"); } }
public async Task ReorgChain_FailsPartialValidation_Nodes_DisconnectedAsync() { using (var builder = NodeBuilder.Create(this)) { var noValidationRulesNetwork = new BitcoinRegTestNoValidationRules(); var minerA = builder.CreateStratisPowNode(this.powNetwork, "cmfr-5-minerA").WithDummyWallet().WithReadyBlockchainData(ReadyBlockchain.BitcoinRegTest10Miner).Start(); var minerB = builder.CreateStratisPowNode(noValidationRulesNetwork, "cmfr-5-minerB").NoValidation().WithDummyWallet().Start(); // Miner B syncs with Miner A TestHelper.ConnectAndSync(minerB, minerA); // Disconnect Miner A from Miner B TestHelper.Disconnect(minerB, minerA); // Miner A continues to mine to height 14 TestHelper.MineBlocks(minerA, 4); TestBase.WaitLoop(() => minerA.FullNode.ConsensusManager().Tip.Height == 14); // Miner B mines 5 more blocks: // Block 6,7,9,10 = valid // Block 8 = invalid var minerBTip = await TestHelper.BuildBlocks.OnNode(minerB).Amount(5).Invalid(14, (coreNode, block) => BlockBuilder.InvalidDuplicateCoinbase(coreNode, block)).BuildAsync(); // Reconnect Miner A to Miner B. TestHelper.ConnectNoCheck(minerA, minerB); // Miner A will disconnect Miner B TestBase.WaitLoop(() => !TestHelper.IsNodeConnectedTo(minerA, minerB)); // Ensure Miner A and Miner B remains on their respective heights. var badBlockOnMinerBChain = minerBTip.GetAncestor(14); Assert.Null(minerA.FullNode.ConsensusManager().Tip.FindAncestorOrSelf(badBlockOnMinerBChain)); TestBase.WaitLoop(() => minerA.FullNode.ConsensusManager().Tip.Height == 14); TestBase.WaitLoop(() => minerB.FullNode.ConsensusManager().Tip.Height == 15); } }
public void ReorgChain_FailsFullValidation_ChainHasBlocksAndHeadersOnly_NodesDisconnected() { using (var builder = NodeBuilder.Create(this)) { var stratisNoValidationRulesNetwork = new StratisRegTestNoValidationRules(); var minerA = builder.CreateStratisPosNode(new StratisRegTest()).WithDummyWallet().Start(); var minerB = builder.CreateStratisPosNode(new StratisRegTest()).WithDummyWallet().Start(); var minerC = builder.CreateStratisPosNode(stratisNoValidationRulesNetwork).NoValidation().WithDummyWallet().Start(); // MinerA mines 5 blocks TestHelper.MineBlocks(minerA, 5); // MinerB and MinerC syncs with MinerA TestHelper.ConnectAndSync(minerA, minerB, minerC); // Disconnect MinerC from MinerA TestHelper.Disconnect(minerA, minerC); // MinerA continues to mine to height 9 TestHelper.MineBlocks(minerA, 4); TestHelper.WaitLoop(() => minerA.FullNode.ConsensusManager().Tip.Height == 9); TestHelper.WaitLoop(() => minerB.FullNode.ConsensusManager().Tip.Height == 9); TestHelper.WaitLoop(() => minerC.FullNode.ConsensusManager().Tip.Height == 5); // MinerB continues to mine to block 13 without block propogation TestHelper.DisableBlockPropagation(minerB, minerA); TestHelper.MineBlocks(minerB, 4); TestHelper.WaitLoop(() => TestHelper.IsNodeSyncedAtHeight(minerA, 9)); TestHelper.WaitLoop(() => TestHelper.IsNodeSyncedAtHeight(minerB, 13)); TestHelper.WaitLoop(() => TestHelper.IsNodeSyncedAtHeight(minerC, 5)); // MinerB mines 5 more blocks: // Block 6,7,9,10 = valid // Block 8 = invalid TestHelper.BuildBlocks.OnNode(minerC).Amount(5).Invalid(8, (coreNode, block) => BlockBuilder.InvalidCoinbaseReward(coreNode, block)).BuildAsync(); // Reconnect MinerA to MinerC. TestHelper.Connect(minerA, minerC); // MinerC should be disconnected from MinerA TestHelper.WaitLoop(() => !TestHelper.IsNodeConnectedTo(minerA, minerC)); // This will cause the reorg chain to fail at block 8 and roll back any changes. TestHelper.WaitLoop(() => TestHelper.IsNodeSyncedAtHeight(minerA, 9)); TestHelper.WaitLoop(() => TestHelper.IsNodeSyncedAtHeight(minerB, 13)); TestHelper.WaitLoop(() => TestHelper.IsNodeSyncedAtHeight(minerC, 10)); } }
public async Task ReorgChain_FailsFullValidation_Reconnect_OldChain_Nodes_ConnectedAsync() { using (var builder = NodeBuilder.Create(this)) { var bitcoinNoValidationRulesNetwork = new BitcoinRegTestNoValidationRules(); var minerA = builder.CreateStratisPowNode(this.powNetwork, "cmfr-1-minerA").WithDummyWallet().WithReadyBlockchainData(ReadyBlockchain.BitcoinRegTest10Miner); var minerB = builder.CreateStratisPowNode(bitcoinNoValidationRulesNetwork, "cmfr-1-minerB").NoValidation().WithDummyWallet().Start(); ChainedHeader minerBChainTip = null; bool interceptorsEnabled = false; bool minerA_Disconnected_ItsOwnChain_ToConnectTo_MinerBs_LongerChain = false; bool minerA_IsConnecting_To_MinerBChain = false; bool minerA_Disconnected_MinerBsChain = false; bool minerA_Reconnected_Its_OwnChain = false; // Configure the interceptor to intercept when Miner A connects Miner B's chain. void interceptorConnect(ChainedHeaderBlock chainedHeaderBlock) { if (!interceptorsEnabled) { return; } if (!minerA_IsConnecting_To_MinerBChain) { if (chainedHeaderBlock.ChainedHeader.Height == 12) { minerA_IsConnecting_To_MinerBChain = minerA.FullNode.ConsensusManager().Tip.HashBlock == minerBChainTip.GetAncestor(12).HashBlock; } return; } if (!minerA_Reconnected_Its_OwnChain) { if (chainedHeaderBlock.ChainedHeader.Height == 14) { minerA_Reconnected_Its_OwnChain = true; } return; } } // Configure the interceptor to intercept when Miner A disconnects Miner B's chain after the reorg. void interceptorDisconnect(ChainedHeaderBlock chainedHeaderBlock) { if (!interceptorsEnabled) { return; } if (!minerA_Disconnected_ItsOwnChain_ToConnectTo_MinerBs_LongerChain) { if (minerA.FullNode.ConsensusManager().Tip.Height == 10) { minerA_Disconnected_ItsOwnChain_ToConnectTo_MinerBs_LongerChain = true; } return; } if (!minerA_Disconnected_MinerBsChain) { if (minerA.FullNode.ConsensusManager().Tip.Height == 10) { minerA_Disconnected_MinerBsChain = true; } return; } } minerA.Start(); minerA.SetConnectInterceptor(interceptorConnect); minerA.SetDisconnectInterceptor(interceptorDisconnect); // Miner B syncs with Miner A TestHelper.ConnectAndSync(minerB, minerA); // Disable Miner A from sending blocks to Miner B TestHelper.DisableBlockPropagation(minerA, minerB); // Miner A continues to mine to height 14 TestHelper.MineBlocks(minerA, 4); TestBase.WaitLoop(() => minerA.FullNode.ConsensusManager().Tip.Height == 14); Assert.Equal(10, minerB.FullNode.ConsensusManager().Tip.Height); // Enable the interceptors so that they are active during the reorg. interceptorsEnabled = true; // Miner B mines 5 more blocks: // Block 6,7,9,10 = valid // Block 8 = invalid minerBChainTip = await TestHelper.BuildBlocks.OnNode(minerB).Amount(5).Invalid(13, (coreNode, block) => BlockBuilder.InvalidCoinbaseReward(coreNode, block)).BuildAsync(); Assert.Equal(15, minerBChainTip.Height); Assert.Equal(15, minerB.FullNode.ConsensusManager().Tip.Height); // Wait until Miner A disconnected its own chain so that it can connect to // Miner B's longer chain. TestBase.WaitLoop(() => minerA_Disconnected_ItsOwnChain_ToConnectTo_MinerBs_LongerChain); // Wait until Miner A has connected Miner B's chain (but failed) TestBase.WaitLoop(() => minerA_IsConnecting_To_MinerBChain); // Wait until Miner A has disconnected Miner B's invalid chain. TestBase.WaitLoop(() => minerA_Disconnected_MinerBsChain); // Wait until Miner A has reconnected its own chain. TestBase.WaitLoop(() => minerA_Reconnected_Its_OwnChain); } }
public void ReorgChain_FailsFullValidation_Reconnect_OldChain_Nodes_Disconnected() { using (var builder = NodeBuilder.Create(this)) { var stratisNoValidationRulesNetwork = new StratisRegTestNoValidationRules(); var minerA = builder.CreateStratisPosNode(this.posNetwork).WithDummyWallet().Start(); var minerB = builder.CreateStratisPosNode(stratisNoValidationRulesNetwork).NoValidation().WithDummyWallet().Start(); // MinerA mines 5 blocks TestHelper.MineBlocks(minerA, 5); // MinerB syncs with MinerA TestHelper.ConnectAndSync(minerB, minerA); // Disconnect miner B from minerA TestHelper.Disconnect(minerB, minerA); // Miner A continues to mine to height 9 TestHelper.MineBlocks(minerA, 4); TestHelper.WaitLoop(() => minerA.FullNode.ConsensusManager().Tip.Height == 9); // MinerB mines 5 more blocks: // Block 6,7,9,10 = valid // Block 8 = invalid TestHelper.BuildBlocks.OnNode(minerB).Amount(5).Invalid(8, (coreNode, block) => BlockBuilder.InvalidCoinbaseReward(coreNode, block)).BuildAsync(); // Reconnect minerA to minerB causing the following to happen: // Reorg from blocks 9 to 5. // Connect blocks 5 to 10 // Block 8 fails. // Reorg from 7 to 5 // Reconnect blocks 6 to 9 TestHelper.Connect(minerA, minerB); TestHelper.WaitLoop(() => minerA.FullNode.ConsensusManager().Tip.Height == 9); TestHelper.WaitLoop(() => minerB.FullNode.ConsensusManager().Tip.Height == 10); } }
private MSAst.Expression ReduceWorker(bool optimizeDynamicConvert) { MSAst.Expression result; if (_tests.Length > 100) { // generate: // if(x) { // body // goto end // } else { // } // elseBody // end: // // to avoid deeply recursive trees which can stack overflow. BlockBuilder builder = new BlockBuilder(); var label = Ast.Label(); for (int i = 0; i < _tests.Length; i++) { IfStatementTest ist = _tests[i]; builder.Add( Ast.Condition( optimizeDynamicConvert ? TransformAndDynamicConvert(ist.Test, typeof(bool)) : GlobalParent.Convert(typeof(bool), Microsoft.Scripting.Actions.ConversionResultKind.ExplicitCast, ist.Test), Ast.Block( TransformMaybeSingleLineSuite(ist.Body, GlobalParent.IndexToLocation(ist.Test.StartIndex)), Ast.Goto(label) ), Utils.Empty() ) ); } if (_else != null) { builder.Add(_else); } builder.Add(Ast.Label(label)); result = builder.ToExpression(); } else { // Now build from the inside out if (_else != null) { result = _else; } else { result = AstUtils.Empty(); } int i = _tests.Length; while (i-- > 0) { IfStatementTest ist = _tests[i]; result = GlobalParent.AddDebugInfoAndVoid( Ast.Condition( optimizeDynamicConvert ? TransformAndDynamicConvert(ist.Test, typeof(bool)) : GlobalParent.Convert(typeof(bool), Microsoft.Scripting.Actions.ConversionResultKind.ExplicitCast, ist.Test), TransformMaybeSingleLineSuite(ist.Body, GlobalParent.IndexToLocation(ist.Test.StartIndex)), result ), new SourceSpan(GlobalParent.IndexToLocation(ist.StartIndex), GlobalParent.IndexToLocation(ist.HeaderIndex)) ); } } return result; }
// Taking the selected transaction receipts from consensus, CreateHeader removes bad // transactions, adds necessary system transactions, emulate the transactions, calculate // stateHash and finally returns a blockHeader public BlockHeader?CreateHeader( ulong index, IReadOnlyCollection <TransactionReceipt> receipts, ulong nonce, out TransactionReceipt[] receiptsTaken ) { Logger.LogTrace("CreateHeader"); if (_blockManager.GetHeight() >= index) { Logger.LogWarning("Block already produced"); receiptsTaken = new TransactionReceipt[] {}; return(null); } // we don't need to verify receipts here // verfification will be done during emulation // But we need to verify the hash as we map the receipts with its hash // we skip the transactions with hash mismatch receipts = receipts.Where(receipt => receipt.Transaction.FullHash(receipt.Signature, HardforkHeights.IsHardfork_9Active(index)).Equals(receipt.Hash)).ToList(); receipts = receipts.OrderBy(receipt => receipt, new ReceiptComparer()) .ToList(); var cycle = index / StakingContract.CycleDuration; var indexInCycle = index % StakingContract.CycleDuration; // try to add necessary system transactions at the end if (cycle > 0 && indexInCycle == StakingContract.AttendanceDetectionDuration) { var txToAdd = DistributeCycleRewardsAndPenaltiesTxReceipt(index); if (receipts.Select(x => x.Hash).Contains(txToAdd.Hash)) { Logger.LogDebug("DistributeCycleRewardsAndPenaltiesTxReceipt is already in txPool"); } else { receipts = receipts.Concat(new[] { txToAdd }).ToList(); } } else if (indexInCycle == StakingContract.VrfSubmissionPhaseDuration) { var txToAdd = FinishVrfLotteryTxReceipt(index); if (receipts.Select(x => x.Hash).Contains(txToAdd.Hash)) { Logger.LogDebug("FinishVrfLotteryTxReceipt is already in txPool"); } else { receipts = receipts.Concat(new[] { txToAdd }).ToList(); } } else if (cycle > 0 && indexInCycle == 0) { var txToAdd = FinishCycleTxReceipt(index); if (receipts.Select(x => x.Hash).Contains(txToAdd.Hash)) { Logger.LogDebug("FinishCycleTxReceipt is already in txPool"); } else { receipts = receipts.Concat(new[] { txToAdd }).ToList(); } } if (_blockManager.LatestBlock().Header.Index + 1 != index) { throw new InvalidOperationException( $"Latest block is {_blockManager.LatestBlock().Header.Index} " + $"with hash {_blockManager.LatestBlock().Hash.ToHex()}, " + $"but we are trying to create block {index}"); } var blockWithTransactions = new BlockBuilder(_blockManager.LatestBlock().Header) .WithTransactions(receipts) .Build(nonce); var(operatingError, removedTxs, stateHash, returnedTxs) = _blockManager.Emulate(blockWithTransactions.Block, blockWithTransactions.Transactions); var badReceipts = new HashSet <TransactionReceipt>(removedTxs.Concat(returnedTxs)); receiptsTaken = receipts.Where(receipt => !badReceipts.Contains(receipt)).ToArray(); blockWithTransactions = new BlockBuilder(_blockManager.LatestBlock().Header) .WithTransactions(receiptsTaken) .Build(nonce); if (operatingError != OperatingError.Ok) { throw new InvalidOperationException($"Cannot assemble block: error {operatingError}"); } return(new BlockHeader { Index = blockWithTransactions.Block.Header.Index, MerkleRoot = blockWithTransactions.Block.Header.MerkleRoot, Nonce = nonce, PrevBlockHash = blockWithTransactions.Block.Header.PrevBlockHash, StateHash = stateHash }); }
protected virtual SyntaxTreeNode RewriteSpan(BlockBuilder parent, Span span) { throw new NotImplementedException(); }
public MethodBuilder With(BlockBuilder block) => new MethodBuilder(_modifiers, _type, _name, _parameters, _typeParameters, null, block);
public async Task <BlockBody[]> BuildBlocksResponse(IList <Keccak> blockHashes, Response flags) { bool consistent = flags.HasFlag(Response.Consistent); bool validSeals = flags.HasFlag(Response.ValidSeals); bool noEmptySpaces = flags.HasFlag(Response.NoEmptySpace); bool justFirst = flags.HasFlag(Response.JustFirst); bool allKnown = flags.HasFlag(Response.AllKnown); bool timeoutOnFullBatch = flags.HasFlag(Response.TimeoutOnFullBatch); bool withTransactions = flags.HasFlag(Response.WithTransactions); if (timeoutOnFullBatch && blockHashes.Count == SyncBatchSize.Max) { throw new TimeoutException(); } BlockHeader startHeader = _blockTree.FindHeader(blockHashes[0], BlockTreeLookupOptions.None); if (startHeader == null) { startHeader = Build.A.BlockHeader.WithHash(blockHashes[0]).TestObject; } BlockHeader[] blockHeaders = new BlockHeader[blockHashes.Count]; BlockBody[] blockBodies = new BlockBody[blockHashes.Count]; blockBodies[0] = new BlockBody(new Transaction[0], new BlockHeader[0]); blockHeaders[0] = startHeader; if (!justFirst) { for (int i = 1; i < blockHashes.Count; i++) { blockHeaders[i] = consistent ? Build.A.BlockHeader.WithParent(blockHeaders[i - 1]).TestObject : Build.A.BlockHeader.WithNumber(blockHeaders[i - 1].Number + 1).TestObject; _testHeaderMapping[startHeader.Number + i] = blockHeaders[i].Hash; BlockHeader header = consistent ? blockHeaders[i] : blockHeaders[i - 1]; BlockBuilder blockBuilder = Build.A.Block.WithHeader(header); if (withTransactions) { blockBuilder.WithTransactions(Build.A.Transaction.WithValue(i * 2).SignedAndResolved().TestObject, Build.A.Transaction.WithValue(i * 2 + 1).SignedAndResolved().TestObject); } Block block = blockBuilder.TestObject; blockBodies[i] = new BlockBody(block.Transactions, block.Ommers); if (allKnown) { _blockTree.SuggestBlock(block); } } } BlockBodiesMessage message = new BlockBodiesMessage(blockBodies); byte[] messageSerialized = _bodiesSerializer.Serialize(message); return(await Task.FromResult(_bodiesSerializer.Deserialize(messageSerialized).Bodies)); }
private void TrackBlock(BlockBuilder builder) { _currentBlock = builder; _blockStack.Push(builder); }
private static TryParseResult TryParseBlock( string tagName, Block block, IEnumerable <TagHelperDescriptor> descriptors, ErrorSink errorSink) { // TODO: Accept more than just spans: https://github.com/aspnet/Razor/issues/96. // The first child will only ever NOT be a Span if a user is doing something like: // <input @checked /> var childSpan = block.Children.First() as Span; if (childSpan == null || childSpan.Kind != SpanKind.Markup) { errorSink.OnError( block.Start, RazorResources.FormatTagHelpers_CannotHaveCSharpInTagDeclaration(tagName), block.Length); return(null); } var builder = new BlockBuilder(block); // If there's only 1 child it means that it's plain text inside of the attribute. // i.e. <div class="plain text in attribute"> if (builder.Children.Count == 1) { return(TryParseSpan(childSpan, descriptors, errorSink)); } var nameSymbols = childSpan .Symbols .OfType <HtmlSymbol>() .SkipWhile(symbol => !HtmlMarkupParser.IsValidAttributeNameSymbol(symbol)) // Skip prefix .TakeWhile(nameSymbol => HtmlMarkupParser.IsValidAttributeNameSymbol(nameSymbol)) .Select(nameSymbol => nameSymbol.Content); var name = string.Concat(nameSymbols); if (string.IsNullOrEmpty(name)) { errorSink.OnError( childSpan.Start, RazorResources.FormatTagHelpers_AttributesMustHaveAName(tagName), childSpan.Length); return(null); } // Have a name now. Able to determine correct isBoundNonStringAttribute value. var result = CreateTryParseResult(name, descriptors); // Remove first child i.e. foo=" builder.Children.RemoveAt(0); // Grabbing last child to check if the attribute value is quoted. var endNode = block.Children.Last(); if (!endNode.IsBlock) { var endSpan = (Span)endNode; // In some malformed cases e.g. <p bar="false', the last Span (false' in the ex.) may contain more // than a single HTML symbol. Do not ignore those other symbols. var symbolCount = endSpan.Symbols.Count(); var endSymbol = symbolCount == 1 ? (HtmlSymbol)endSpan.Symbols.First() : null; // Checking to see if it's a quoted attribute, if so we should remove end quote if (endSymbol != null && IsQuote(endSymbol)) { builder.Children.RemoveAt(builder.Children.Count - 1); } } // We need to rebuild the chunk generators of the builder and its children (this is needed to // ensure we don't do special attribute chunk generation since this is a tag helper). block = RebuildChunkGenerators(builder.Build(), result.IsBoundAttribute); // If there's only 1 child at this point its value could be a simple markup span (treated differently than // block level elements for attributes). if (block.Children.Count() == 1) { var child = block.Children.First() as Span; if (child != null) { // After pulling apart the block we just have a value span. var spanBuilder = new SpanBuilder(child); result.AttributeValueNode = CreateMarkupAttribute(spanBuilder, result.IsBoundNonStringAttribute); return(result); } } var isFirstSpan = true; result.AttributeValueNode = ConvertToMarkupAttributeBlock( block, (parentBlock, span) => { // If the attribute was requested by a tag helper but the corresponding property was not a // string, then treat its value as code. A non-string value can be any C# value so we need // to ensure the SyntaxTreeNode reflects that. if (result.IsBoundNonStringAttribute) { // For bound non-string attributes, we'll only allow a transition span to appear at the very // beginning of the attribute expression. All later transitions would appear as code so that // they are part of the generated output. E.g. // key="@value" -> MyTagHelper.key = value // key=" @value" -> MyTagHelper.key = @value // key="1 + @case" -> MyTagHelper.key = 1 + @case // key="@int + @case" -> MyTagHelper.key = int + @case // key="@(a + b) -> MyTagHelper.key = a + b // key="4 + @(a + b)" -> MyTagHelper.key = 4 + @(a + b) if (isFirstSpan && span.Kind == SpanKind.Transition) { // do nothing. } else { var spanBuilder = new SpanBuilder(span); if (parentBlock.Type == BlockType.Expression && (spanBuilder.Kind == SpanKind.Transition || spanBuilder.Kind == SpanKind.MetaCode)) { // Change to a MarkupChunkGenerator so that the '@' \ parenthesis is generated as part of the output. spanBuilder.ChunkGenerator = new MarkupChunkGenerator(); } spanBuilder.Kind = SpanKind.Code; span = spanBuilder.Build(); } } isFirstSpan = false; return(span); }); return(result); }
private static KeyValuePair <string, SyntaxTreeNode> ParseBlock( Block block, IReadOnlyDictionary <string, string> attributeValueTypes) { // TODO: Accept more than just spans: https://github.com/aspnet/Razor/issues/96. // The first child will only ever NOT be a Span if a user is doing something like: // <input @checked /> var childSpan = block.Children.First() as Span; if (childSpan == null) { throw new InvalidOperationException(RazorResources.TagHelpers_CannotHaveCSharpInTagDeclaration); } var builder = new BlockBuilder(block); // If there's only 1 child it means that it's plain text inside of the attribute. // i.e. <div class="plain text in attribute"> if (builder.Children.Count == 1) { return(ParseSpan(childSpan, attributeValueTypes)); } var textSymbol = childSpan.Symbols.FirstHtmlSymbolAs(HtmlSymbolType.Text); var name = textSymbol != null ? textSymbol.Content : null; if (name == null) { throw new InvalidOperationException(RazorResources.TagHelpers_AttributesMustHaveAName); } // Remove first child i.e. foo=" builder.Children.RemoveAt(0); // Grabbing last child to check if the attribute value is quoted. var endNode = block.Children.Last(); if (!endNode.IsBlock) { var endSpan = (Span)endNode; var endSymbol = (HtmlSymbol)endSpan.Symbols.Last(); // Checking to see if it's a quoted attribute, if so we should remove end quote if (IsQuote(endSymbol)) { builder.Children.RemoveAt(builder.Children.Count - 1); } } // We need to rebuild the code generators of the builder and its children (this is needed to // ensure we don't do special attribute code generation since this is a tag helper). block = RebuildCodeGenerators(builder.Build()); // If there's only 1 child at this point its value could be a simple markup span (treated differently than // block level elements for attributes). if (block.Children.Count() == 1) { var child = block.Children.First() as Span; if (child != null) { // After pulling apart the block we just have a value span. var spanBuilder = new SpanBuilder(child); return(CreateMarkupAttribute(name, spanBuilder, attributeValueTypes)); } } return(new KeyValuePair <string, SyntaxTreeNode>(name, block)); }
private async Task Initialize(bool auRa = false) { IDbProvider dbProvider = await TestMemDbProvider.InitAsync(); ISpecProvider specProvider = MainnetSpecProvider.Instance; _jsonRpcConfig = new JsonRpcConfig(); IEthereumEcdsa ethereumEcdsa = new EthereumEcdsa(specProvider.ChainId, LimboLogs.Instance); ITxStorage txStorage = new InMemoryTxStorage(); _stateDb = new MemDb(); ITrieStore trieStore = new TrieStore(_stateDb, LimboLogs.Instance); _stateProvider = new StateProvider(trieStore, new MemDb(), LimboLogs.Instance); _stateProvider.CreateAccount(TestItem.AddressA, 1000.Ether()); _stateProvider.CreateAccount(TestItem.AddressB, 1000.Ether()); _stateProvider.CreateAccount(TestItem.AddressC, 1000.Ether()); byte[] code = Bytes.FromHexString("0xabcd"); Keccak codeHash = Keccak.Compute(code); _stateProvider.UpdateCode(code); _stateProvider.UpdateCodeHash(TestItem.AddressA, codeHash, specProvider.GenesisSpec); IStorageProvider storageProvider = new StorageProvider(trieStore, _stateProvider, LimboLogs.Instance); storageProvider.Set(new StorageCell(TestItem.AddressA, UInt256.One), Bytes.FromHexString("0xabcdef")); storageProvider.Commit(); _stateProvider.Commit(specProvider.GenesisSpec); _stateProvider.CommitTree(0); IChainLevelInfoRepository chainLevels = new ChainLevelInfoRepository(dbProvider); IBlockTree blockTree = new BlockTree(dbProvider, chainLevels, specProvider, NullBloomStorage.Instance, LimboLogs.Instance); ITxPool txPool = new TxPool.TxPool(txStorage, ethereumEcdsa, new ChainHeadSpecProvider(specProvider, blockTree), new TxPoolConfig(), _stateProvider, new TxValidator(specProvider.ChainId), LimboLogs.Instance); IReceiptStorage receiptStorage = new InMemoryReceiptStorage(); VirtualMachine virtualMachine = new VirtualMachine(_stateProvider, storageProvider, new BlockhashProvider(blockTree, LimboLogs.Instance), specProvider, LimboLogs.Instance); TransactionProcessor txProcessor = new TransactionProcessor(specProvider, _stateProvider, storageProvider, virtualMachine, LimboLogs.Instance); IBlockProcessor blockProcessor = new BlockProcessor( specProvider, Always.Valid, new RewardCalculator(specProvider), txProcessor, _stateProvider, storageProvider, txPool, receiptStorage, NullWitnessCollector.Instance, LimboLogs.Instance); RecoverSignatures signatureRecovery = new RecoverSignatures(ethereumEcdsa, txPool, specProvider, LimboLogs.Instance); BlockchainProcessor blockchainProcessor = new BlockchainProcessor(blockTree, blockProcessor, signatureRecovery, LimboLogs.Instance, BlockchainProcessor.Options.Default); blockchainProcessor.Start(); ManualResetEventSlim resetEvent = new ManualResetEventSlim(false); blockTree.NewHeadBlock += (s, e) => { Console.WriteLine(e.Block.Header.Hash); if (e.Block.Number == 9) { resetEvent.Set(); } }; var genesisBlockBuilder = Build.A.Block.Genesis.WithStateRoot(new Keccak("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")); if (auRa) { genesisBlockBuilder.WithAura(0, new byte[65]); } Block genesis = genesisBlockBuilder.TestObject; blockTree.SuggestBlock(genesis); Block previousBlock = genesis; for (int i = 1; i < 10; i++) { List <Transaction> transactions = new List <Transaction>(); for (int j = 0; j < i; j++) { transactions.Add(Build.A.Transaction.WithNonce((UInt256)j).SignedAndResolved().TestObject); } BlockBuilder builder = Build.A.Block.WithNumber(i).WithParent(previousBlock).WithTransactions(MuirGlacier.Instance, transactions.ToArray()).WithStateRoot(new Keccak("0x1ef7300d8961797263939a3d29bbba4ccf1702fabf02d8ad7a20b454edb6fd2f")); if (auRa) { builder.WithAura(i, i.ToByteArray()); } Block block = builder.TestObject; blockTree.SuggestBlock(block); previousBlock = block; } ReceiptsRecovery receiptsRecovery = new ReceiptsRecovery(new EthereumEcdsa(specProvider.ChainId, LimboLogs.Instance), specProvider); IReceiptFinder receiptFinder = new FullInfoReceiptFinder(receiptStorage, receiptsRecovery, blockTree); resetEvent.Wait(2000); _traceModule = new TraceModule(receiptFinder, new Tracer(_stateProvider, blockchainProcessor), blockTree, _jsonRpcConfig); }
private static Block RebuildCodeGenerators(Block block) { var builder = new BlockBuilder(block); var isDynamic = builder.CodeGenerator is DynamicAttributeBlockCodeGenerator; // We don't want any attribute specific logic here, null out the block code generator. if (isDynamic || builder.CodeGenerator is AttributeBlockCodeGenerator) { builder.CodeGenerator = BlockCodeGenerator.Null; } for (var i = 0; i < builder.Children.Count; i++) { var child = builder.Children[i]; if (child.IsBlock) { // The child is a block, recurse down into the block to rebuild its children builder.Children[i] = RebuildCodeGenerators((Block)child); } else { var childSpan = (Span)child; ISpanCodeGenerator newCodeGenerator = null; var literalGenerator = childSpan.CodeGenerator as LiteralAttributeCodeGenerator; if (literalGenerator != null) { if (literalGenerator.ValueGenerator == null || literalGenerator.ValueGenerator.Value == null) { newCodeGenerator = new MarkupCodeGenerator(); } else { newCodeGenerator = literalGenerator.ValueGenerator.Value; } } else if (isDynamic && childSpan.CodeGenerator == SpanCodeGenerator.Null) { // Usually the dynamic code generator handles rendering the null code generators underneath // it. This doesn't make sense in terms of tag helpers though, we need to change null code // generators to markup code generators. newCodeGenerator = new MarkupCodeGenerator(); } // If we have a new code generator we'll need to re-build the child if (newCodeGenerator != null) { var childSpanBuilder = new SpanBuilder(childSpan) { CodeGenerator = newCodeGenerator }; builder.Children[i] = childSpanBuilder.Build(); } } } return(builder.Build()); }
// // rescue stmts ... if (StandardError === $!) { stmts; } // rescue <types> stmts ... temp1 = type1; ...; if (<temp1> === $! || ...) { stmts; } // rescue <types> => <lvalue> stmts ... temp1 = type1; ...; if (<temp1> === $! || ...) { <lvalue> = $!; stmts; } // internal IfStatementTest /*!*/ Transform(AstGenerator /*!*/ gen, ResultOperation resultOperation) { Assert.NotNull(gen); MSA.Expression condition; if (_types.Length != 0 || _splatType != null) { var comparisonSiteStorage = Ast.Constant(new BinaryOpStorage(gen.Context)); if (_types.Length == 0) { // splat only: condition = MakeCompareSplattedExceptions(gen, comparisonSiteStorage, TransformSplatType(gen)); } else if (_types.Length == 1 && _splatType == null) { condition = MakeCompareException(gen, comparisonSiteStorage, _types[0].TransformRead(gen)); } else { // forall{i}: <temps[i]> = evaluate type[i] var temps = new MSA.Expression[_types.Length + (_splatType != null ? 1 : 0)]; var exprs = new BlockBuilder(); int i = 0; while (i < _types.Length) { var tmp = gen.CurrentScope.DefineHiddenVariable("#type_" + i, typeof(object)); temps[i] = tmp; exprs.Add(Ast.Assign(tmp, _types[i].TransformRead(gen))); i++; } if (_splatType != null) { var tmp = gen.CurrentScope.DefineHiddenVariable("#type_" + i, typeof(IList)); temps[i] = tmp; exprs.Add(Ast.Assign(tmp, TransformSplatType(gen))); i++; } Debug.Assert(i == temps.Length); // CompareException(<temps[0]>) || ... CompareException(<temps[n]>) || CompareSplattedExceptions(<splatTypes>) i = 0; condition = MakeCompareException(gen, comparisonSiteStorage, temps[i++]); while (i < _types.Length) { condition = Ast.OrElse(condition, MakeCompareException(gen, comparisonSiteStorage, temps[i++])); } if (_splatType != null) { condition = Ast.OrElse(condition, MakeCompareSplattedExceptions(gen, comparisonSiteStorage, temps[i++])); } Debug.Assert(i == temps.Length); // (temps[0] = type[0], ..., temps[n] == type[n], condition) exprs.Add(condition); condition = exprs; } } else { condition = Methods.CompareDefaultException.OpCall(gen.CurrentScopeVariable); } return(AstUtils.IfCondition(condition, gen.TransformStatements( // <lvalue> = e; (_target != null) ? _target.TransformWrite(gen, Methods.GetCurrentException.OpCall(gen.CurrentScopeVariable)) : null, // body: _statements, resultOperation ) )); }
public void TestFolders() { byte[] seed = { 0, 0, 0, 0 }; RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(seed); Console.WriteLine("preparing the authority block"); KeyPair root = new KeyPair(rng); BiscuitBuilder builder = Biscuit.Token.Biscuit.Builder(rng, root); builder.AddRight("/folder1/file1", "read"); builder.AddRight("/folder1/file1", "write"); builder.AddRight("/folder1/file2", "read"); builder.AddRight("/folder1/file2", "write"); builder.AddRight("/folder2/file3", "read"); Console.WriteLine(builder.Build()); Biscuit.Token.Biscuit b = builder.Build().Right; Console.WriteLine(b.Print()); BlockBuilder block2 = b.CreateBlock(); block2.ResourcePrefix("/folder1/"); block2.CheckRight("read"); KeyPair keypair2 = new KeyPair(rng); Biscuit.Token.Biscuit b2 = b.Attenuate(rng, keypair2, block2.Build()).Right; Verifier v1 = b2.Verify(root.ToPublicKey()).Right; v1.AddResource("/folder1/file1"); v1.AddOperation("read"); v1.Allow(); Either <Error, long> res = v1.Verify(); Assert.IsTrue(res.IsRight); Verifier v2 = b2.Verify(root.ToPublicKey()).Right; v2.AddResource("/folder2/file3"); v2.AddOperation("read"); v2.Allow(); res = v2.Verify(); Assert.IsTrue(res.IsLeft); Verifier v3 = b2.Verify(root.ToPublicKey()).Right; v3.AddResource("/folder2/file1"); v3.AddOperation("write"); v3.Allow(); res = v3.Verify(); Error e = res.Left; Assert.IsTrue(res.IsLeft); Console.WriteLine(v3.PrintWorld()); foreach (FailedCheck f in e.FailedCheck().Get()) { Console.WriteLine(f.ToString()); } Assert.AreEqual( new FailedLogic(new LogicError.FailedChecks(Arrays.AsList <FailedCheck>( new FailedCheck.FailedBlock(1, 0, "check if resource(#ambient, $resource), $resource.starts_with(\"/folder1/\")"), new FailedCheck.FailedBlock(1, 1, "check if resource(#ambient, $resource), operation(#ambient, #read), right(#authority, $resource, #read)") ))), e); }
public Builder <T> WithGenesisBlockBuilder(BlockBuilder blockBuilder) { _blockchain.GenesisBlockBuilder = blockBuilder; return(this); }
public void TestBasic() { byte[] seed = { 0, 0, 0, 0 }; RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(seed); Console.WriteLine("preparing the authority block"); KeyPair root = new KeyPair(rng); SymbolTable symbols = Biscuit.Token.Biscuit.DefaultSymbolTable(); BlockBuilder authority_builder = new BlockBuilder(0, symbols); authority_builder.AddFact(Utils.Fact("right", Arrays.AsList(Utils.Symbol("authority"), Utils.Symbol("file1"), Utils.Symbol("read")))); authority_builder.AddFact(Utils.Fact("right", Arrays.AsList(Utils.Symbol("authority"), Utils.Symbol("file2"), Utils.Symbol("read")))); authority_builder.AddFact(Utils.Fact("right", Arrays.AsList(Utils.Symbol("authority"), Utils.Symbol("file1"), Utils.Symbol("write")))); Biscuit.Token.Biscuit b = Biscuit.Token.Biscuit.Make(rng, root, Biscuit.Token.Biscuit.DefaultSymbolTable(), authority_builder.Build()).Right; Console.WriteLine(b.Print()); Console.WriteLine("serializing the first token"); byte[] data = b.Serialize().Right; Console.Write("data len: "); Console.WriteLine(data.Length); //Console.WriteLine(hex(data)); Console.WriteLine("deserializing the first token"); Biscuit.Token.Biscuit deser = Biscuit.Token.Biscuit.FromBytes(data).Right; Console.WriteLine(deser.Print()); // SECOND BLOCK Console.WriteLine("preparing the second block"); KeyPair keypair2 = new KeyPair(rng); BlockBuilder builder = deser.CreateBlock(); builder.AddCheck(Utils.Check(Utils.Rule( "caveat1", Arrays.AsList(Utils.Var("resource")), Arrays.AsList( Utils.Pred("resource", Arrays.AsList(Utils.Symbol("ambient"), Utils.Var("resource"))), Utils.Pred("operation", Arrays.AsList(Utils.Symbol("ambient"), Utils.Symbol("read"))), Utils.Pred("right", Arrays.AsList(Utils.Symbol("authority"), Utils.Var("resource"), Utils.Symbol("read"))) ) ))); Biscuit.Token.Biscuit b2 = deser.Attenuate(rng, keypair2, builder.Build()).Right; Console.WriteLine(b2.Print()); Console.WriteLine("serializing the second token"); byte[] data2 = b2.Serialize().Right; Console.Write("data len: "); Console.WriteLine(data2.Length); //Console.WriteLine(hex(data2)); Console.WriteLine("deserializing the second token"); Biscuit.Token.Biscuit deser2 = Biscuit.Token.Biscuit.FromBytes(data2).Right; Console.WriteLine(deser2.Print()); // THIRD BLOCK Console.WriteLine("preparing the third block"); KeyPair keypair3 = new KeyPair(rng); BlockBuilder builder3 = deser2.CreateBlock(); builder3.AddCheck(Utils.Check(Utils.Rule( "caveat2", Arrays.AsList(Utils.Symbol("file1")), Arrays.AsList( Utils.Pred("resource", Arrays.AsList(Utils.Symbol("ambient"), Utils.Symbol("file1"))) ) ))); Biscuit.Token.Biscuit b3 = deser2.Attenuate(rng, keypair3, builder3.Build()).Right; Console.WriteLine(b3.Print()); Console.WriteLine("serializing the third token"); byte[] data3 = b3.Serialize().Right; Console.Write("data len: "); Console.WriteLine(data3.Length); //Console.WriteLine(hex(data3)); Console.WriteLine("deserializing the third token"); Biscuit.Token.Biscuit final_token = Biscuit.Token.Biscuit.FromBytes(data3).Right; Console.WriteLine(final_token.Print()); // check Console.WriteLine("will check the token for resource=file1 and operation=read"); SymbolTable check_symbols = new SymbolTable(final_token.Symbols); List <Fact> ambient_facts = Arrays.AsList( Utils.Fact("resource", Arrays.AsList(Utils.Symbol("ambient"), Utils.Symbol("file1"))).Convert(check_symbols), Utils.Fact("operation", Arrays.AsList(Utils.Symbol("ambient"), Utils.Symbol("read"))).Convert(check_symbols) ); Either <Error, Dictionary <string, HashSet <Fact> > > res = final_token.Check(check_symbols, ambient_facts, new List <Rule>(), new List <Check>(), new Dictionary <string, Rule>()); Assert.IsTrue(res.IsRight); Console.WriteLine("will check the token for resource=file2 and operation=write"); SymbolTable check_symbols2 = new SymbolTable(final_token.Symbols); List <Fact> ambient_facts2 = Arrays.AsList( Utils.Fact("resource", Arrays.AsList(Utils.Symbol("ambient"), Utils.Symbol("file2"))).Convert(check_symbols2), Utils.Fact("operation", Arrays.AsList(Utils.Symbol("ambient"), Utils.Symbol("write"))).Convert(check_symbols2) ); Either <Error, Dictionary <string, HashSet <Fact> > > res2 = final_token.Check(check_symbols2, ambient_facts2, new List <Rule>(), new List <Check>(), new Dictionary <string, Rule>()); Assert.IsTrue(res2.IsLeft); Console.WriteLine(res2.Left); Assert.AreEqual( new FailedLogic(new LogicError.FailedChecks(Arrays.AsList <FailedCheck>( new FailedCheck.FailedBlock(1, 0, "check if resource(#ambient, $resource), operation(#ambient, #read), right(#authority, $resource, #read)"), new FailedCheck.FailedBlock(2, 0, "check if resource(#ambient, #file1)") ))), res2.Left); }
public async Task ReorgChain_FailsFullValidation_ChainHasBlocksAndHeadersOnly_NodesDisconnectedAsync() { using (var builder = NodeBuilder.Create(this)) { var noValidationRulesNetwork = new BitcoinRegTestNoValidationRules("regtest1"); var minerA = builder.CreateStratisPowNode(this.powNetwork, "cmfr-6-minerA").WithDummyWallet().Start(); var minerB = builder.CreateStratisPowNode(this.powNetwork, "cmfr-6-minerB").WithDummyWallet().Start(); var minerC = builder.CreateStratisPowNode(noValidationRulesNetwork, "cmfr-6-minerC").NoValidation().WithDummyWallet().Start(); // Mine 10 blocks with minerA. We cannot use a premade chain as it adversely affects the max tip age calculation, causing sporadic sync errors. TestHelper.MineBlocks(minerA, 10); TestBase.WaitLoop(() => minerA.FullNode.ConsensusManager().Tip.Height == 10); // MinerB and MinerC syncs with MinerA TestHelper.ConnectAndSync(minerA, minerB, minerC); // Disconnect MinerC from MinerA TestHelper.Disconnect(minerA, minerC); // MinerA continues to mine to height 14 TestHelper.MineBlocks(minerA, 4); TestBase.WaitLoopMessage(() => { return(minerA.FullNode.ConsensusManager().Tip.Height == 14, minerA.FullNode.ConsensusManager().Tip.Height.ToString()); }); TestBase.WaitLoopMessage(() => { return(minerB.FullNode.ConsensusManager().Tip.Height == 14, minerB.FullNode.ConsensusManager().Tip.Height.ToString()); }); TestBase.WaitLoopMessage(() => { return(minerC.FullNode.ConsensusManager().Tip.Height == 10, minerC.FullNode.ConsensusManager().Tip.Height.ToString()); }); // MinerB continues to mine to block 13 without block propogation TestHelper.DisableBlockPropagation(minerB, minerA); TestHelper.MineBlocks(minerB, 4); TestBase.WaitLoop(() => TestHelper.IsNodeSyncedAtHeight(minerA, 14)); TestBase.WaitLoop(() => TestHelper.IsNodeSyncedAtHeight(minerB, 18)); TestBase.WaitLoop(() => TestHelper.IsNodeSyncedAtHeight(minerC, 10)); // MinerB mines 5 more blocks: // Block 6,7,9,10 = valid // Block 8 = invalid await TestHelper.BuildBlocks.OnNode(minerC).Amount(5).Invalid(13, (coreNode, block) => BlockBuilder.InvalidCoinbaseReward(coreNode, block)).BuildAsync(); // Reconnect MinerA to MinerC. TestHelper.ConnectNoCheck(minerA, minerC); // MinerC should be disconnected from MinerA TestBase.WaitLoop(() => !TestHelper.IsNodeConnectedTo(minerA, minerC)); // This will cause the reorg chain to fail at block 8 and roll back any changes. TestBase.WaitLoopMessage(() => { return(minerA.FullNode.ConsensusManager().Tip.Height == 14, minerA.FullNode.ConsensusManager().Tip.Height.ToString()); }); TestBase.WaitLoopMessage(() => { return(minerB.FullNode.ConsensusManager().Tip.Height == 18, minerB.FullNode.ConsensusManager().Tip.Height.ToString()); }); TestBase.WaitLoopMessage(() => { return(minerC.FullNode.ConsensusManager().Tip.Height == 15, minerC.FullNode.ConsensusManager().Tip.Height.ToString()); }); } }
public void TestSealedTokens() { byte[] seed = { 0, 0, 0, 0 }; RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(seed); Console.WriteLine("preparing the authority block"); KeyPair root = new KeyPair(rng); SymbolTable symbols = Biscuit.Token.Biscuit.DefaultSymbolTable(); BlockBuilder authority_builder = new BlockBuilder(0, symbols); authority_builder.AddFact(Utils.Fact("right", Arrays.AsList(Utils.Symbol("authority"), Utils.Symbol("file1"), Utils.Symbol("read")))); authority_builder.AddFact(Utils.Fact("right", Arrays.AsList(Utils.Symbol("authority"), Utils.Symbol("file2"), Utils.Symbol("read")))); authority_builder.AddFact(Utils.Fact("right", Arrays.AsList(Utils.Symbol("authority"), Utils.Symbol("file1"), Utils.Symbol("write")))); Biscuit.Token.Biscuit b = Biscuit.Token.Biscuit.Make(rng, root, Biscuit.Token.Biscuit.DefaultSymbolTable(), authority_builder.Build()).Right; Console.WriteLine(b.Print()); Console.WriteLine("serializing the first token"); byte[] data = b.Serialize().Right; Console.Write("data len: "); Console.WriteLine(data.Length); //Console.WriteLine(hex(data)); Console.WriteLine("deserializing the first token"); Biscuit.Token.Biscuit deser = Biscuit.Token.Biscuit.FromBytes(data).Right; Console.WriteLine(deser.Print()); // SECOND BLOCK Console.WriteLine("preparing the second block"); KeyPair keypair2 = new KeyPair(rng); BlockBuilder builder = deser.CreateBlock(); builder.AddCheck(Utils.Check(Utils.Rule( "caveat1", Arrays.AsList(Utils.Var("resource")), Arrays.AsList( Utils.Pred("resource", Arrays.AsList(Utils.Symbol("ambient"), Utils.Var("resource"))), Utils.Pred("operation", Arrays.AsList(Utils.Symbol("ambient"), Utils.Symbol("read"))), Utils.Pred("right", Arrays.AsList(Utils.Symbol("authority"), Utils.Var("resource"), Utils.Symbol("read"))) ) ))); Biscuit.Token.Biscuit b2 = deser.Attenuate(rng, keypair2, builder.Build()).Right; Console.WriteLine(b2.Print()); Console.WriteLine("sealing the second token"); byte[] testkey = Encoding.UTF8.GetBytes("testkey"); var sealedd = b2.Seal(testkey).Right; Console.Write("sealed data len: "); Console.WriteLine(sealedd.Length); Console.WriteLine("deserializing the sealed token with an invalid key"); Error e = Biscuit.Token.Biscuit.FromSealed(sealedd, Encoding.UTF8.GetBytes("not this key")).Left; Console.WriteLine(e); Assert.AreEqual(new SealedSignature(), e); Console.WriteLine("deserializing the sealed token with a valid key"); Biscuit.Token.Biscuit deser2 = Biscuit.Token.Biscuit.FromSealed(sealedd, Encoding.UTF8.GetBytes("testkey")).Right; Console.WriteLine(deser2.Print()); Console.WriteLine("trying to attenuate to a sealed token"); _ = deser2.CreateBlock(); _ = deser2.Attenuate(rng, keypair2, builder.Build()).Left; Verifier v = deser2.VerifySealed().Right; Console.WriteLine(v.PrintWorld()); }
public async Task ReorgChain_FailsFullValidation_Reconnect_OldChain_FromSecondMiner_DisconnectedAsync() { using (var builder = NodeBuilder.Create(this)) { var noValidationRulesNetwork = new BitcoinRegTestNoValidationRules(); var minerA = builder.CreateStratisPowNode(this.powNetwork, "cmfr-3-minerA").WithDummyWallet().Start(); var syncer = builder.CreateStratisPowNode(this.powNetwork, "cmfr-3-syncer").Start(); var minerB = builder.CreateStratisPowNode(noValidationRulesNetwork, "cmfr-3-minerB").NoValidation().WithDummyWallet().Start(); // MinerA mines 5 blocks TestHelper.MineBlocks(minerA, 5); // MinerB and Syncer syncs with MinerA TestHelper.ConnectAndSync(minerB, minerA); TestHelper.ConnectAndSync(syncer, minerA); // Disconnect minerB from miner A TestHelper.Disconnect(minerB, minerA); TestBase.WaitLoop(() => !TestHelper.IsNodeConnected(minerB)); // Miner A continues to mine to height 9 TestHelper.MineBlocks(minerA, 4); TestBase.WaitLoop(() => minerA.FullNode.ConsensusManager().Tip.Height == 9); TestBase.WaitLoop(() => minerB.FullNode.ConsensusManager().Tip.Height == 5); TestBase.WaitLoop(() => syncer.FullNode.ConsensusManager().Tip.Height == 9); // Disconnect syncer from minerA TestHelper.Disconnect(syncer, minerA); TestBase.WaitLoop(() => !TestHelper.IsNodeConnected(minerA)); // MinerB mines 5 more blocks: // Block 6,7,9,10 = valid // Block 8 = invalid await TestHelper.BuildBlocks.OnNode(minerB).Amount(5).Invalid(8, (coreNode, block) => BlockBuilder.InvalidCoinbaseReward(coreNode, block)).BuildAsync(); // Reconnect syncer to minerB causing the following to happen: // Reorg from blocks 9 to 5. // Connect blocks 5 to 10 // Block 8 fails. // Reorg from 7 to 5 // Reconnect blocks 6 to 9 TestHelper.ConnectNoCheck(syncer, minerB); TestHelper.AreNodesSynced(minerA, syncer); TestBase.WaitLoop(() => minerA.FullNode.ConsensusManager().Tip.Height == 9); TestBase.WaitLoop(() => minerB.FullNode.ConsensusManager().Tip.Height == 10); TestBase.WaitLoop(() => syncer.FullNode.ConsensusManager().Tip.Height == 9); } }
public DnnClientResources(Page page, IBlockBuilder blockBuilder, ILog parentLog) : base("Dnn.JsCss", parentLog) { Page = page; BlockBuilder = blockBuilder as BlockBuilder; Header = new DnnJsApiHeader(Log); }
private LGraph buildBlocks() { lir_.entry = new LBlock(lir_.entry_pc); BlockBuilder builder = new BlockBuilder(lir_); LBlock entry = builder.parse(); // Get an RPO ordering of the blocks, since we don't have predecessors yet. LBlock[] blocks = BlockAnalysis.Order(entry); if (!BlockAnalysis.IsReducible(blocks)) throw new Exception("control flow graph is not reducible"); // Split critical edges in the graph (is this even needed?) BlockAnalysis.SplitCriticalEdges(blocks); // Reorder the blocks since we could have introduced new nodes. blocks = BlockAnalysis.Order(entry); //Debug.Assert(BlockAnalysis.IsReducible(blocks)); BlockAnalysis.ComputeDominators(blocks); BlockAnalysis.ComputeImmediateDominators(blocks); BlockAnalysis.ComputeDominatorTree(blocks); BlockAnalysis.FindLoops(blocks); LGraph graph = new LGraph(); graph.blocks = blocks; graph.entry = blocks[0]; if (lir_.argDepth > 0) graph.nargs = ((lir_.argDepth - 12) / 4) + 1; else graph.nargs = 0; return graph; }
protected virtual SyntaxTreeNode RewriteBlock(BlockBuilder parent, Block block) { throw new NotImplementedException(); }
// // rescue stmts ... if (StandardError === $!) { stmts; } // rescue <types> stmts ... temp1 = type1; ...; if (<temp1> === $! || ...) { stmts; } // rescue <types> => <lvalue> stmts ... temp1 = type1; ...; if (<temp1> === $! || ...) { <lvalue> = $!; stmts; } // internal IfStatementTest/*!*/ Transform(AstGenerator/*!*/ gen, ResultOperation resultOperation) { Assert.NotNull(gen); MSA.Expression condition; if (_types.Length != 0 || _splatType != null) { var comparisonSiteStorage = Ast.Constant(new BinaryOpStorage(gen.Context)); if (_types.Length == 0) { // splat only: condition = MakeCompareSplattedExceptions(gen, comparisonSiteStorage, TransformSplatType(gen)); } else if (_types.Length == 1 && _splatType == null) { condition = MakeCompareException(gen, comparisonSiteStorage, _types[0].TransformRead(gen)); } else { // forall{i}: <temps[i]> = evaluate type[i] var temps = new MSA.Expression[_types.Length + (_splatType != null ? 1 : 0)]; var exprs = new BlockBuilder(); int i = 0; while (i < _types.Length) { var tmp = gen.CurrentScope.DefineHiddenVariable("#type_" + i, typeof(object)); temps[i] = tmp; exprs.Add(Ast.Assign(tmp, _types[i].TransformRead(gen))); i++; } if (_splatType != null) { var tmp = gen.CurrentScope.DefineHiddenVariable("#type_" + i, typeof(IList)); temps[i] = tmp; exprs.Add(Ast.Assign(tmp, TransformSplatType(gen))); i++; } Debug.Assert(i == temps.Length); // CompareException(<temps[0]>) || ... CompareException(<temps[n]>) || CompareSplattedExceptions(<splatTypes>) i = 0; condition = MakeCompareException(gen, comparisonSiteStorage, temps[i++]); while (i < _types.Length) { condition = Ast.OrElse(condition, MakeCompareException(gen, comparisonSiteStorage, temps[i++])); } if (_splatType != null) { condition = Ast.OrElse(condition, MakeCompareSplattedExceptions(gen, comparisonSiteStorage, temps[i++])); } Debug.Assert(i == temps.Length); // (temps[0] = type[0], ..., temps[n] == type[n], condition) exprs.Add(condition); condition = exprs; } } else { condition = Methods.CompareDefaultException.OpCall(gen.CurrentScopeVariable); } return AstUtils.IfCondition(condition, gen.TransformStatements( // <lvalue> = e; (_target != null) ? _target.TransformWrite(gen, Methods.GetCurrentException.OpCall(gen.CurrentScopeVariable)) : null, // body: _statements, resultOperation ) ); }
public static DoBuilder Create(BlockBuilder body) => new DoBuilder(body);