Ejemplo n.º 1
0
        protected override async Task <JToken> GetConstructorParamsAsync()
        {
            var(targetAbi, targetTvc) = TestClient.Package(Target);

            TargetAddr = (await Client.Abi.EncodeMessageAsync(new ParamsOfEncodeMessage
            {
                Abi = targetAbi,
                DeploySet = new DeploySet
                {
                    Tvc = targetTvc
                },
                Signer = new Signer.Keys
                {
                    KeysProperty = Keys
                },
                CallSet = new CallSet
                {
                    FunctionName = "constructor"
                }
            })).Address;

            TargetAbi = targetAbi;

            await Client.GetGramsFromGiverAsync(TargetAddr);

            var serializer = new TonSerializer();

            return(new
            {
                targetAbi = serializer.Serialize((targetAbi as Abi.Contract).Value).ToHexString(),
                targetAddr = TargetAddr
            }.ToJson());
        }
 public TonSerializerTests(ITestOutputHelper outputHelper)
 {
     _serializer = new TonSerializer(new XUnitTestLogger(outputHelper));
 }
        public async Task Should_Suspend_Resume()
        {
            var keys = await _client.Crypto.GenerateRandomSignKeysAsync();

            var(abi, tvc) = TestClient.Package("Hello");

            var deployParams = new ParamsOfEncodeMessage
            {
                Abi       = abi,
                DeploySet = new DeploySet
                {
                    Tvc = tvc
                },
                Signer = new Signer.Keys
                {
                    KeysProperty = keys
                },
                CallSet = new CallSet
                {
                    FunctionName = "constructor"
                }
            };

            var msg = await _client.Abi.EncodeMessageAsync(deployParams);

            var address        = msg.Address;
            var transactionIds = new List <string>();
            var notifications  = new List <ClientError>();

            var subscriptionClient = TestClient.Create(_logger);

            var handle = await subscriptionClient.Net.SubscribeCollectionAsync(new ParamsOfSubscribeCollection
            {
                Collection = "transactions",
                Filter     = new
                {
                    account_addr = new { eq = address },
                    status       = new { eq = 3 } // Finalized
                }.ToJson(),
                Result = "id account_addr"
            }, (json, result) =>
            {
                switch (result)
                {
                case 100:     // OK
                    transactionIds.Add((string)json.SelectToken("result.id"));
                    break;

                case 101:     // Error
                    var clientError = new TonSerializer(_logger).Deserialize <ClientError>(json);
                    notifications.Add(clientError);
                    break;

                default:
                    throw new NotSupportedException($"Response code ${result} not supported");
                }

                return(Task.CompletedTask);
            });

            // send grams to create first transaction
            await _client.GetGramsFromGiverAsync(msg.Address);

            await Task.Delay(TimeSpan.FromSeconds(1));

            // check that transaction is received
            Assert.Single(transactionIds);

            // and no error notifications
            Assert.Empty(notifications);

            // suspend subscription
            await subscriptionClient.Net.SuspendAsync();

            // deploy to create second transaction
            await _client.Processing.ProcessMessageAsync(new ParamsOfProcessMessage
            {
                MessageEncodeParams = deployParams,
                SendEvents          = false
            });

            // create second subscription while network is suspended
            var handle2 = await subscriptionClient.Net.SubscribeCollectionAsync(new ParamsOfSubscribeCollection
            {
                Collection = "transactions",
                Filter     = new
                {
                    account_addr = new { eq = msg.Address },
                    status       = new { eq = 3 } // Finalized
                }.ToJson(),
                Result = "id account_addr"
            }, (json, result) =>
            {
                switch (result)
                {
                case 100:     // OK
                    transactionIds.Add((string)json.SelectToken("result.id"));
                    break;

                case 101:     // Error
                    var clientError = new TonSerializer(_logger).Deserialize <ClientError>(json);
                    notifications.Add(clientError);
                    break;

                default:
                    throw new NotSupportedException($"Response code ${result} not supported");
                }

                return(Task.CompletedTask);
            });

            await Task.Delay(TimeSpan.FromMilliseconds(500));

            // check that second transaction is not received when subscription suspended
            Assert.Single(transactionIds);
            Assert.Equal(2, notifications.Count);
            Assert.All(notifications, n =>
                       Assert.Equal((uint)NetErrorCode.NetworkModuleSuspended, n.Code));

            // resume subscription
            await subscriptionClient.Net.ResumeAsync();

            // run contract function to create new transaction
            await subscriptionClient.Processing.ProcessMessageAsync(new ParamsOfProcessMessage
            {
                MessageEncodeParams = new ParamsOfEncodeMessage
                {
                    Abi    = abi,
                    Signer = new Signer.Keys
                    {
                        KeysProperty = keys
                    },
                    Address = msg.Address,
                    CallSet = new CallSet
                    {
                        FunctionName = "touch"
                    }
                },
                SendEvents = false
            });

            // give some time for subscription to receive all data
            await Task.Delay(TimeSpan.FromSeconds(10));

            // check that third transaction is now received after resume
            Assert.Equal(3, transactionIds.Count);
            Assert.Equal(2, transactionIds.Distinct().Count());

            // and both subscriptions received notification about resume
            Assert.Equal(4, notifications.Count);
            Assert.Equal(2, notifications.Count(n => n.Code == (uint)NetErrorCode.NetworkModuleSuspended));
            Assert.Equal(2, notifications.Count(n => n.Code == (uint)NetErrorCode.NetworkModuleResumed));

            await subscriptionClient.Net.UnsubscribeAsync(handle);

            await subscriptionClient.Net.UnsubscribeAsync(handle2);
        }
        private async Task ExecuteFromStateAsync(BrowserData state, bool callStart)
        {
            if (callStart)
            {
                var res = await _debot.Client.Debot.FetchAsync(new ParamsOfFetch
                {
                    Address = state.Address
                });

                var serializer  = new TonSerializer();
                var expectedAbi = serializer.Deserialize <JToken>(state.Info.Dabi);
                var actualAbi   = serializer.Deserialize <JToken>(res.Info.Dabi);
                Assert.Equal(expectedAbi, actualAbi);
                if (state.Info != null)
                {
                    Assert.NotNull(res.Info);
                    Assert.Equal(state.Info.Author, res.Info.Author);
                    Assert.Equal(state.Info.Dabi, res.Info.Dabi);
                    Assert.Equal(state.Info.Hello, res.Info.Hello);
                    Assert.Equal(state.Info.Icon, res.Info.Icon);
                    Assert.Equal(state.Info.Interfaces ?? new string[0], res.Info.Interfaces);
                    Assert.Equal(state.Info.Caption, res.Info.Caption);
                    Assert.Equal(state.Info.Language, res.Info.Language);
                    Assert.Equal(state.Info.Name, res.Info.Name);
                    Assert.Equal(state.Info.Publisher, res.Info.Publisher);
                }
                else
                {
                    Assert.Null(res.Info);
                }
            }

            var handle = await FetchDebotAsync(state, state.Address);

            if (callStart)
            {
                await _debot.Client.Debot.StartAsync(new ParamsOfStart
                {
                    DebotHandle = handle.DebotHandle
                });
            }

            while (!state.Finished)
            {
                await HandleMessageQueueAsync(handle, state);

                DebotAction action;
                using (var step = await state.Current.LockAsync())
                {
                    if (!step.Instance.AvailableActions.Any())
                    {
                        break;
                    }

                    using (var next = await state.Next.LockAsync())
                    {
                        step.Instance.Step = next.Instance.RemoveFirst();
                    }

                    step.Instance.Outputs.Clear();
                    action = step.Instance.AvailableActions[step.Instance.Step.Choice - 1];
                }

                _logger.Information($"Executing action {action.Name}");

                await _debot.Client.Debot.ExecuteAsync(new ParamsOfExecute
                {
                    Action      = action,
                    DebotHandle = handle.DebotHandle
                });

                using (var step = await state.Current.LockAsync())
                {
                    var leftArr  = step.Instance.Step.Outputs;
                    var rightArr = step.Instance.Outputs;
                    Assert.Equal(leftArr.Count, rightArr.Count);
                    for (var i = 0; i < leftArr.Count; ++i)
                    {
                        var left  = leftArr[i];
                        var right = rightArr[i];
                        Assert.NotNull(left);
                        Assert.NotNull(right);
                        var pos = left.IndexOf("{}", StringComparison.Ordinal);
                        if (pos >= 0)
                        {
                            Assert.Equal(left.Substring(0, pos), right.Substring(0, pos));
                        }
                        else
                        {
                            Assert.Equal(left, right);
                        }
                    }

                    Assert.Empty(step.Instance.Step.Inputs);
                    Assert.Empty(step.Instance.Step.Invokes);

                    if (!step.Instance.AvailableActions.Any())
                    {
                        break;
                    }
                }
            }

            using (var next = await state.Next.LockAsync())
            {
                Assert.Empty(next.Instance);
            }

            using var terminal = await state.Terminal.LockAsync();

            Assert.Empty(terminal.Instance.Messages);
        }