Example #1
0
        public static async Task Run([PerperStreamTrigger] PerperStreamContext context,
                                     [Perper("self")] ValidatorKey self,
                                     [PerperStream("inputStream")] IAsyncEnumerable <IHashed <AgentInput> > inputStream,
                                     [PerperStream("outputStream")] IAsyncCollector <AgentOutput> outputStream,
                                     CancellationToken cancellationToken,
                                     ILogger logger)
        {
            await inputStream.ForEachAsync(async input =>
            {
                try
                {
                    var agentContext = await context.CallWorkerAsync <AgentContext <object> >(nameof(RuntimeWorker), new
                    {
                        state   = input.Value.State,
                        sender  = new AgentCapability(input.Value.Sender),
                        message = input.Value.Message
                    }, cancellationToken);

                    await outputStream.AddAsync(new AgentOutput
                    {
                        Previous = input.Hash,
                        State    = agentContext.State,
                        Commands = agentContext.Commands
                    }, cancellationToken);
                }
                catch (Exception e)
                {
                    logger.LogError(e.ToString());
                }
            }, cancellationToken);
        }
Example #2
0
        public static async Task Run([PerperStreamTrigger] PerperStreamContext context,
                                     [Perper("self")] ValidatorKey self,
                                     [PerperStream("stepsStream")] IAsyncEnumerable <IHashed <IAgentStep> > stepsStream,
                                     [PerperStream("currentProposerStream")] IAsyncEnumerable <ValidatorKey> currentProposerStream,
                                     [PerperStream("outputStream")] IAsyncCollector <IHashed <IAgentStep> > outputStream)
        {
            var state = await context.FetchStateAsync <State>() ?? new State();

            async Task processPending()
            {
                if (state.LastProposer != null && state.LastProposer.Equals(self) && state.LastCommit != null)
                {
                    await outputStream.AddAsync(state.LastCommit);

                    state.LastCommit   = null; // Do not produce the same commit twice
                    state.LastProposer = null; // Do not produce the next commit before the proposer is updated
                }
            };

            await Task.WhenAll(
                currentProposerStream.ForEachAsync(async currentProposer =>
            {
                state.LastProposer = currentProposer;
                await processPending();
                await context.UpdateStateAsync(state);
            }, CancellationToken.None),

                stepsStream.ForEachAsync(async commit =>
            {
                state.LastCommit = commit;
                await processPending();
                await context.UpdateStateAsync(state);
            }, CancellationToken.None));
        }
Example #3
0
        public virtual Validator <T> NewValidator <T>(ValidatorOptions options)
        {
            var key = new ValidatorKey()
            {
                validatorType    = typeof(T),
                validatorOptions = options
            };

            Validator <T> retval;

            if (!ValidatorCacheContainer <T> .validators.TryGetValue(key, out retval))
            {
                retval = DoNewValidator <T>(options);

                var newValidators = new Dictionary <ValidatorKey, Validator <T> >();

                foreach (var keyValue in ValidatorCacheContainer <T> .validators)
                {
                    newValidators[keyValue.Key] = keyValue.Value;
                }

                newValidators[key] = retval;

                ValidatorCacheContainer <T> .validators = newValidators;
            }

            return(retval);
        }
Example #4
0
        public static async Task Run([PerperStreamTrigger] PerperStreamContext context,
                                     [Perper("self")] ValidatorKey self,
                                     [Perper("privateKey")] ECParameters privateKey,
                                     [PerperStream("dataStream")] IAsyncEnumerable <object> dataStream,
                                     [PerperStream("outputStream")] IAsyncCollector <ISigned <object> > outputStream)
        {
            await dataStream.ForEachAsync(async item =>
            {
                var bytes     = IpfsJsonSettings.ObjectToBytes(item);
                var signature = ValidatorKey.GenerateSignature(privateKey, bytes);

                await outputStream.AddAsync(Signed.Create(item, self, signature));
            }, CancellationToken.None);
        }
Example #5
0
        public static async Task Run([PerperStreamTrigger] PerperStreamContext context,
                                     CancellationToken cancellationToken)
        {
            ECParameters privateKey;
            ValidatorKey self;

            using (var dsa = ECDsa.Create())
            {
                privateKey = dsa.ExportParameters(true);
                self       = new ValidatorKey {
                    Key = dsa.ExportParameters(false)
                };
            }

            var ipfsGateway = "http://127.0.0.1:5001";

            await using var agentZeroStream = await context.StreamFunctionAsync(nameof (IpfsInput), new
            {
                ipfsGateway,
                topic = "apocryph-agent-0"
            });

            await using var _inputVerifierStream = await context.StreamFunctionAsync(nameof (StepSignatureVerifier), new
            {
                stepsStream = agentZeroStream,
            });

            await using var inputVerifierStream = await context.StreamFunctionAsync(nameof (IpfsLoader), new
            {
                ipfsGateway,
                hashStream = _inputVerifierStream
            });

            await using var validatorSetsStream = await context.StreamFunctionAsync(nameof (ValidatorSets), new
            {
                inputVerifierStream
            });

            await using var validatorSchedulerStream = await context.StreamActionAsync(nameof (ValidatorScheduler), new
            {
                validatorSetsStream,
                ipfsGateway,
                privateKey,
                self
            });

            await context.BindOutput(cancellationToken);
        }
Example #6
0
        public static async Task Run([PerperStreamTrigger(RunOnStartup = true)] PerperStreamContext context,
                                     CancellationToken cancellationToken)
        {
            var keys         = new List <(ECParameters, ValidatorKey)>();
            var validatorSet = new ValidatorSet();

            for (var i = 0; i < 1; i++)
            {
                using var dsa = ECDsa.Create(ECCurve.NamedCurves.nistP521);
                var privateKey = dsa.ExportParameters(true);
                var publicKey  = new ValidatorKey {
                    Key = dsa.ExportParameters(false)
                };
                keys.Add((privateKey, publicKey));
                validatorSet.Weights.Add(publicKey, 10);
            }

            var ipfsGateway = "http://127.0.0.1:5001";

            await using var _validatorSetsStream = await context.StreamFunctionAsync("TestDataGenerator", new
            {
                delay = TimeSpan.FromSeconds(20),
                data  = validatorSet
            });

            await using var validatorSetsStream = await context.StreamFunctionAsync(nameof (IpfsSaver), new
            {
                ipfsGateway,
                dataStream = _validatorSetsStream
            });

            await using var validatorLauncherStreams = new AsyncDisposableList();
            foreach (var(privateKey, self) in keys)
            {
                validatorLauncherStreams.Add(
                    await context.StreamActionAsync(nameof(ValidatorLauncher), new
                {
                    agentId  = "0",
                    services = new [] { "Sample", "IpfsInput" },
                    validatorSetsStream,
                    ipfsGateway,
                    privateKey,
                    self
                }));
            }

            await context.BindOutput(cancellationToken);
        }
Example #7
0
        public static async Task Run([PerperStreamTrigger] PerperStreamContext context,
                                     [PerperStream("validatorSetsStream")] IAsyncEnumerable <Dictionary <string, ValidatorSet> > validatorSetsStream,
                                     [Perper("ipfsGateway")] string ipfsGateway,
                                     [Perper("privateKey")] ECParameters privateKey,
                                     [Perper("self")] ValidatorKey self)
        {
            var runningStreams = new Dictionary <KeyValuePair <string, ValidatorSet>, IAsyncDisposable>();

            await validatorSetsStream.ForEachAsync(async validatorSets =>
            {
                // FIXME: Instead of restarting when validator set changes, send validator sets as a seperate stream

                var filteredValidatorSets = validatorSets
                                            .Where(kv => kv.Value.Weights.ContainsKey(self));

                var toStop = new HashSet <KeyValuePair <string, ValidatorSet> >(runningStreams.Keys);

                foreach (var kv in filteredValidatorSets)
                {
                    toStop.Remove(kv);

                    if (!runningStreams.ContainsKey(kv))
                    {
                        var agentId        = kv.Key;
                        var validatorSet   = kv.Value;
                        runningStreams[kv] = await context.StreamActionAsync(nameof(ValidatorLauncher), new
                        {
                            ipfsGateway,
                            agentId      = agentId,
                            validatorSet = validatorSet,
                            privateKey,
                            self
                        });
                    }
                }

                foreach (var kv in toStop)
                {
                    await runningStreams[kv].DisposeAsync();
                    runningStreams.Remove(kv);
                }
            }, CancellationToken.None);
        }
Example #8
0
        public static async Task Run([PerperStreamTrigger] PerperStreamContext context,
                                     [Perper("agentId")] string agentId,
                                     [Perper("services")] string[] services,
                                     [Perper("validatorSetsStream")] object[] validatorSetsStream,
                                     [Perper("ipfsGateway")] string ipfsGateway,
                                     [Perper("privateKey")] ECParameters privateKey,
                                     [Perper("self")] ValidatorKey self,
                                     CancellationToken cancellationToken)
        {
            var genesisMessage = ("", (object)new InitMessage());

            await using var validatorSchedulerStream = await context.StreamActionAsync(nameof (PBFTConsensus), new
            {
                agentId,
                services,
                validatorSetsStream,
                genesisMessage,
                ipfsGateway,
                privateKey,
                self
            });

            await context.BindOutput(cancellationToken);
        }
 public static void SubscribeUserInput(this IAgentContext context, ValidatorKey key)
 {
     context.SendServiceMessage("IpfsInput", key);
 }