Beispiel #1
0
        public static async Task Start([PerperTrigger] object?input, IContext context, IHashResolver hashResolver, IPeerConnector peerConnector)
        {
            var(executorAgent, _) = await context.StartAgentAsync <object?>("Apocryph-Executor", null);

            await executorAgent.CallActionAsync("Register", (Hash.From("AgentOne"), context.Agent, "AgentOne"));

            await executorAgent.CallActionAsync("Register", (Hash.From("AgentTwo"), context.Agent, "AgentTwo"));

            var agentStates = new[] {
                new AgentState(0, ReferenceData.From(new AgentOne.AgentOneState()), Hash.From("AgentOne")),
                new AgentState(1, ReferenceData.From(new AgentTwo.AgentTwoState()), Hash.From("AgentTwo"))
            };

            var agentStatesTree = await MerkleTreeBuilder.CreateRootFromValues(hashResolver, agentStates, 2);

            Chain chain;

            if (Environment.GetEnvironmentVariable("SAMPLE_AGENTS_CONSENSUS") == "Dummy")
            {
                chain = new Chain(new ChainState(agentStatesTree, agentStates.Length), "Apocryph-DummyConsensus", null, 1);
            }
            else
            {
                var snowballParameters = await hashResolver.StoreAsync <object>(new SnowballParameters(15, 0.8, 25));

                chain = new Chain(new ChainState(agentStatesTree, agentStates.Length), "Apocryph-SnowballConsensus", snowballParameters, 60);
            }

            var chainId = await hashResolver.StoreAsync(chain);

            var(_, kothStates) = await context.StartAgentAsync <IAsyncEnumerable <(Hash <Chain>, Slot?[])> >("Apocryph-KoTH", null);

            var minerAgentTask = context.StartAgentAsync <object?>("Apocryph-KoTH-SimpleMiner", (kothStates, new Hash <Chain>[] { chainId }));
        public static async Task <MerkleTreeLeafBuilder <T>[]> CreateFromValues <T>(IHashResolver resolver, IEnumerable <T> values, int maxChildren)
        {
            var result = new List <MerkleTreeLeafBuilder <T> >();

            foreach (var value in values)
            {
                var leaf = new MerkleTreeLeaf <T>(value);
                var hash = await resolver.StoreAsync <IMerkleTree <T> >(leaf);

                var builder = new MerkleTreeLeafBuilder <T>(leaf, hash);
                result.Add(builder);
            }

            var currentLayer = new Queue <IMerkleTreeBuilder <T> >(result);

            while (currentLayer.Count > 1)
            {
                var previousLayer = currentLayer;
                currentLayer = new Queue <IMerkleTreeBuilder <T> >((previousLayer.Count - 1) / maxChildren + 1);

                while (previousLayer.Count > 0)
                {
                    if (previousLayer.Count == 1)
                    {
                        currentLayer.Enqueue(previousLayer.Dequeue()); // Optimization; we never want single-element nodes
                        break;
                    }

                    var children = new IMerkleTreeBuilder <T> [Math.Min(previousLayer.Count, maxChildren)];
                    var hashes   = new Hash <IMerkleTree <T> > [children.Length];
                    for (var i = 0; i < children.Length; i++)
                    {
                        children[i] = previousLayer.Dequeue();
                        hashes[i]   = children[i].Hash;
                    }
                    var node = new MerkleTreeNode <T>(hashes);
                    var hash = await resolver.StoreAsync <IMerkleTree <T> >(node);

                    var builder = new MerkleTreeNodeBuilder <T>(node, hash);
                    for (var i = 0; i < children.Length; i++)
                    {
                        children[i].Parent        = builder;
                        children[i].IndexInParent = i;
                    }
                    currentLayer.Enqueue(builder);
                }
            }

            return(result.ToArray());
        }