Exemplo n.º 1
0
            /// <summary>
            /// 呼叫本地logic
            /// </summary>
            /// <param name="logic"></param>
            /// <param name="action"></param>
            /// <param name="p"></param>
            /// <returns></returns>
            public object CallLocalLogic(string logic, string action, FrameDLRObject p)
            {
                var copyp = (WebParameter)_logic.CallContext_Parameter.WebParam.Clone();
                var copyd = (GoData)_logic.CallContext_DataCollection.WebData.Clone();

                copyp.RequestResourceName = logic;
                copyp.Action = action;
                ResourceManage rema = new ResourceManage();

                copyp.SetValue(ParameterKey.RESOURCE_MANAGER, rema);
                var defaulttoken = TransactionToken.NewToken();

                copyp.TransTokenList.Add(defaulttoken);
                copyp.SetValue(ParameterKey.TOKEN, defaulttoken);
                copyp.SetValue("IsAjaxAsync", false);
                if (p != null)
                {
                    foreach (var key in p.Keys)
                    {
                        copyp.SetValue(DomainKey.CUSTOMER_PARAMETER, key, p.GetValue(key));
                    }
                }

                return(CallLocalLogic(logic, action, copyp, copyd));
            }
Exemplo n.º 2
0
        public async Task <ResponseCheckTx> CheckTx(TransactionToken transactionToken, object data, RequestCheckTx request, ServerCallContext context)
        {
            if (!(data is RequestTransfer payload))
            {
                return(ResponseHelper.Check.NoPayload());
            }

            if (!IsVerifiedCaller(transactionToken, payload.NewOwner))
            {
                return(ResponseHelper.Check.Unauthorized());
            }

            _logger.LogInformation("Received valid CheckTx request");

            var callNumber = await _callNumberRepository.Get(payload.PhoneNumber);

            if (callNumber == null)
            {
                return(ResponseHelper.Check.Create(CodeType.UnknownCallNumber, "Unknown call number."));
            }

            if (callNumber.TransferRequestStarted.HasValue)
            {
                return(ResponseHelper.Check.Create(CodeType.TransferAlreadyStarted, "Transfer has already been started."));
            }

            _logger.LogInformation("CheckTx Result: ok");

            return(ResponseHelper.Check.Ok());
        }
Exemplo n.º 3
0
        public void ShouldRouteTransaction()
        {
            var transactionHandlerRouter = _serviceProvider.GetService(typeof(TransactionHandlerRouter)) as TransactionHandlerRouter;

            // initialize certificates list
            if (_serviceProvider.GetService(typeof(IOptions <ApplicationSettings>)) is IOptions <ApplicationSettings> applicationSettings)
            {
                applicationSettings.Value.SecuritySettings.PublicCertificates = new List <X509Certificate2>();
            }

            var transaction = new CreateNumber {
                Owner = "A", PhoneNumber = "1", TransactionTime = DateTime.Now
            };
            var json  = JsonConvert.SerializeObject(transaction, new TransactionSerializerSettings());
            var token = new TransactionToken(Encoding.UTF8.GetBytes(json));
            // fake signing
            var signatureField = typeof(TransactionToken).GetField("_signature", BindingFlags.NonPublic | BindingFlags.Instance);

            signatureField.SetValue(token, Encoding.UTF8.GetBytes("1234"));

            var request = new RequestCheckTx {
                Tx = ByteString.CopyFromUtf8(token.ToTokenString())
            };

            // fake context
            var ctor    = typeof(ServerCallContext).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance).First();
            var context = (ServerCallContext)ctor.Invoke(new object[] { null, "TX", "localhost", DateTime.Now, new Metadata(), CancellationToken.None, null, null });

            var expected        = ResponseHelper.Check.Unauthorized();
            var responseCheckTx = transactionHandlerRouter?.RouteCheckTx(request, context).Result;

            Assert.AreEqual(expected, responseCheckTx);
        }
Exemplo n.º 4
0
        private static async Task Output(BaseTransaction tx, bool copyToClipboard, string party)
        {
            tx.TransactionTime = DateTime.Now;
            var jsonString       = JsonConvert.SerializeObject(tx, new TransactionSerializerSettings());
            var byteArray        = Encoding.UTF8.GetBytes(jsonString);
            var transactionToken = new TransactionToken(byteArray);

            var currentDirectory = Directory.GetCurrentDirectory();

            if (!currentDirectory.Contains("netcoreapp"))
            {
                throw new Exception("Please execute the request creator within netcoreapp2.0 folder.");
            }

            var basePath    = Path.Combine(currentDirectory, "..", "..", "..", "..", "..", "certificates");
            var certificate = new X509Certificate2(Path.Combine(basePath, $"{party}.p12"), "thinktecture");

            transactionToken.Sign(certificate);

            var tokenString = transactionToken.ToTokenString();

            Console.WriteLine("Sending the following tokenstring...");
            Console.WriteLine(tokenString);

            if (copyToClipboard)
            {
                CopyToClipboard(tokenString);
            }

            Console.WriteLine(await MakeRequest(tokenString));
        }
        public async Task <ResponseDeliverTx> DeliverTx(TransactionToken transactionToken, object data, RequestDeliverTx request, ServerCallContext context)
        {
            if (!(data is DenyTransferRequest payload))
            {
                return(ResponseHelper.Deliver.NoPayload());
            }

            var callNumber = await _callNumberRepository.Get(payload.PhoneNumber);

            if (callNumber == null)
            {
                return(ResponseHelper.Deliver.Create(CodeType.UnknownCallNumber, "Unknown call number."));
            }

            if (!IsVerifiedCaller(transactionToken, callNumber.Owner))
            {
                return(ResponseHelper.Deliver.Unauthorized());
            }

            callNumber.TransferRequestedTo    = null;
            callNumber.TransferRequestStarted = null;

            await _callNumberRepository.Update(callNumber);

            return(ResponseHelper.Deliver.Ok());
        }
        private DOCollection GetPropertyValue()
        {
            _rm    = (ResourceManage)_p.GetValue(ParameterKey.RESOURCE_MANAGER);
            _token = (TransactionToken)_p.GetValue(ParameterKey.TOKEN);
            DOCollection rtn = null;

            lock (lockobj)
            {
                rtn = GetCache(_p.PropertyName);
                if (rtn == null)
                {
                    Init(_p);
                    var action = GetSourceDefinition(_p.PropertyName);
                    if (action != null)
                    {
                        CacheSetting setting = new CacheSetting();
                        rtn = action.Invoke(setting);

                        if (setting.IsCache)
                        {
                            SetCache(_p.PropertyName, rtn, setting.CacheExpiration, setting.CacheSlidingExpiration);
                        }
                    }
                    After(_p);
                }
            }
            return(rtn);
        }
Exemplo n.º 7
0
        public T CreateInstance <T>(TransactionToken transToken) where T : IResourceEntity, ITransaction
        {
            if (transToken.IsExpired)
            {
                throw new Exception("Token已经过期无法创建资源!");
            }

            Type t   = typeof(T);
            T    rtn = (T)Activator.CreateInstance(t, true);

            if (rtn is ITransaction)
            {
                AddEntity(transToken, (IResourceEntity)rtn);
                if (transToken.CurrentStatus == TransactionToken.TransStatus.Begin)
                {
                    ((ITransaction)rtn).BeginTransaction(transToken.IsolationLevel);
                }
            }
            else
            {
                throw new Exception(t.FullName + "不是ITransaction");
            }

            return(rtn);
        }
        public async Task <ResponseCheckTx> CheckTx(TransactionToken transactionToken, object data, RequestCheckTx request, ServerCallContext context)
        {
            if (!(data is DenyTransferRequest payload))
            {
                return(ResponseHelper.Check.NoPayload());
            }

            var callNumber = await _callNumberRepository.Get(payload.PhoneNumber);

            if (callNumber == null)
            {
                return(ResponseHelper.Check.Create(CodeType.UnknownCallNumber, "Unknown call number."));
            }

            if (!IsVerifiedCaller(transactionToken, callNumber.Owner))
            {
                return(ResponseHelper.Check.Unauthorized());
            }

            if (callNumber.TransferRequestedTo != payload.NewOwner)
            {
                return(ResponseHelper.Check.Create(CodeType.UnknownNewOwner, "Unknown new owner."));
            }

            if (!callNumber.TransferRequestStarted.HasValue)
            {
                return(ResponseHelper.Check.Create(CodeType.NoTransferInitiated, "Transfer was not initiated."));
            }

            return(ResponseHelper.Check.Ok());
        }
        public async Task <TransactionToken> GenerateToken(Guid transactionId, TokenType type)
        {
            var(login, user) = await _userDataManager.AddCurrentUserIfNeeded();

            var tokenString = _stringGenerator.GenerateIdentifier(100, CharsInToken.CapitalSmallNumeric_);
            var token       = new TransactionToken
            {
                TransactionTokenId = Guid.NewGuid(),
                IssuedAtUtc        = DateTime.UtcNow,
                UseAfterUtc        = DateTime.UtcNow,
                UseBeforeUtc       = DateTime.UtcNow.AddDays(6),
                Status             = TokenStatus.Ok,
                Token         = tokenString,
                Type          = type,
                IssuerLoginId = login.LoginId
            };

            if (type == TokenType.Receiving)
            {
                token.RegistrationId = transactionId;
            }
            else if (type == TokenType.Returning)
            {
                token.ReceivingId = transactionId;
            }

            var model = _tokensRepo.Add(token);
            await _tokensRepo.SaveChangesAsync();

            return(model);
        }
Exemplo n.º 10
0
        public TransactionToken BeginTrans(FrameIsolationLevel level)
        {
            TransactionToken newtoken = TransactionToken.NewToken();

            newtoken.Begin();
            _p.TransTokenList.Add(newtoken);
            return(newtoken);
        }
Exemplo n.º 11
0
        public override T Clone <T>()
        {
            var rtn = base.Clone <T>();

            rtn.SetValue(ParameterKey.TOKEN, TransactionToken.NewToken());
            rtn.SetValue(ParameterKey.RESOURCE_MANAGER, new ResourceManage());
            return(rtn);
        }
Exemplo n.º 12
0
        private (ITransactionHandler Handler, TransactionToken TransactionToken, BaseTransaction Payload) ResolveTransactionHandler(Func <ByteString> byteStringAccessor)
        {
            var byteString       = byteStringAccessor();
            var transactionToken = TransactionToken.FromByteString(byteString);

            var payload = JsonConvert.DeserializeObject <BaseTransaction>(Encoding.UTF8.GetString(transactionToken.Data), _transactionSerializerSettings);

            return(_transactionHandlerFactory.CreateHandlerFor(payload), transactionToken, payload);
        }
Exemplo n.º 13
0
 /// <summary>
 /// 新增资源对象
 /// </summary>
 /// <param name="token">生命周期token</param>
 /// <param name="e">资源实例</param>
 public void AddEntity(TransactionToken token, IResourceEntity e)
 {
     if (!_transd.ContainsKey(token.UniqueID))
     {
         ResourceCollection rc = new ResourceCollection();
         _transd.Add(token.UniqueID, rc);
     }
     _transd[token.UniqueID].Add(e.ID, e);
 }
Exemplo n.º 14
0
        /// <summary>
        /// 复制对象
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            var t   = this.GetType();
            var rtn = (ParameterStd)Activator.CreateInstance(t);

            rtn.SetValue(ParameterKey.TOKEN, TransactionToken.NewToken());
            rtn.SetValue(ParameterKey.RESOURCE_MANAGER, new ResourceManage());
            return(rtn);
        }
Exemplo n.º 15
0
        public async Task <ResponseDeliverTx> DeliverTx(TransactionToken transactionToken, BaseTransaction data,
                                                        RequestDeliverTx request, ServerCallContext context)
        {
            if (!(data is T payload))
            {
                return(ResponseHelper.Deliver.NoPayload());
            }

            return(await DeliverTx(transactionToken, payload, request, context).ConfigureAwait(false));
        }
Exemplo n.º 16
0
            /// <summary>
            /// 获得一个新的UnitParamter
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="rm">指定的资源管理器</param>
            /// <param name="token">指定的TransactionToken</param>
            /// <returns></returns>
            public T NewUnitParameter <T>(ResourceManage rm, TransactionToken token) where T : UnitParameter
            {
                var t = Activator.CreateInstance <T>();

                t.SetValue(ParameterKey.TOKEN, token);
                t.SetValue(ParameterKey.RESOURCE_MANAGER, rm);
                foreach (var item in _logic.CallContext_Parameter.Domain(DomainKey.CONFIG))
                {
                    t.SetValue(DomainKey.CONFIG, item.Key, item.Value);
                }
                return(t);
            }
        public void Validate(TransactionToken token, string issuer)
        {
            var certificate = _settings.SecuritySettings.PublicCertificates.SingleOrDefault(i =>
                                                                                            i.GetNameInfo(X509NameType.SimpleName, false).Equals(issuer, StringComparison.OrdinalIgnoreCase));

            if (certificate == null)
            {
                return;
            }

            token.Validate(certificate);
        }
        private TransactionToken CreateSignedToken(BaseTransaction tx)
        {
            tx.TransactionTime = DateTime.Now;
            var jsonString       = JsonConvert.SerializeObject(tx, new TransactionSerializerSettings());
            var byteArray        = Encoding.UTF8.GetBytes(jsonString);
            var transactionToken = new TransactionToken(byteArray);

            var basePath    = Path.Combine(_environment.WebRootPath);
            var certificate = new X509Certificate2(Path.Combine(basePath, $"{GetParty()}.p12"), "thinktecture");

            transactionToken.Sign(certificate);

            return(transactionToken);
        }
        public async Task <ResponseCheckTx> CheckTx(TransactionToken transactionToken, CreateNumber payload, RequestCheckTx request, ServerCallContext context)
        {
            if (!IsVerifiedCaller(transactionToken))
            {
                return(ResponseHelper.Check.Unauthorized());
            }

            _logger.LogInformation("Received valid CheckTx request");

            var result = await _callNumberRepository.Get(payload.PhoneNumber);

            _logger.LogInformation($"CheckTx Result: {result == null}");
            return(ResponseHelper.Check.Create(result == null ? CodeType.Ok : CodeType.PhoneNumberAlreadyExists, result == null ? "" : "Phonenumber already exists."));
        }
Exemplo n.º 20
0
 /// <summary>
 /// 释放资源
 /// </summary>
 /// <param name="token">TransactionToken</param>
 public void Release(TransactionToken token)
 {
     lock (lockobj)
     {
         if (_transd.ContainsKey(token.UniqueID))
         {
             foreach (IResourceEntity e in _transd[token.UniqueID].Values)
             {
                 e.Release();
             }
         }
         token.Release();
         this._transd.Remove(token.UniqueID);
     }
 }
Exemplo n.º 21
0
        protected virtual void BeforeProcess(TParameter p, TData d)
        {
            //获取请求的资源和参数
            ResourceManage rema = new ResourceManage();

            p.SetValue(ParameterKey.RESOURCE_MANAGER, rema);
            var defaulttoken = TransactionToken.NewToken();

            p.TransTokenList.Add(defaulttoken);
            p.SetValue(ParameterKey.TOKEN, defaulttoken);
            p.SetValue("IsAjaxAsync", false);

            ProcessRequestInfo(p, d);
            ProcessRequestSession(p, d);
            ProcessResponseCookie(p, d);
        }
Exemplo n.º 22
0
        public void CreateGenesisBlock(
            string ownerAddress,
            string nativeTokenName,
            string nativeTokenSymbol,
            long initialSupply,
            short decimals)
        {
            if (LastBlock != null || (ApplicationState.PendingRecords != null && ApplicationState.PendingRecords.Count > 0))
            {
                throw new Exception("Error CreateGenesisBlock: Chain already exist.");
            }

            List <Transaction> transactions = new List <Transaction>();

            //Deploy native token to genesis block
            TransactionToken nativeToken = new TransactionToken();

            nativeToken.Name          = nativeTokenName;
            nativeToken.Symbol        = nativeTokenSymbol;
            nativeToken.Decimals      = decimals;
            nativeToken.TransactionId = GenerateTransactionId(nativeToken);
            transactions.Add(nativeToken);

            //Transfer native token supply to owner address
            TransactionTransfer transfer = new TransactionTransfer();

            transfer.TokenSymbol   = nativeTokenSymbol;
            transfer.FromAddress   = null;
            transfer.ToAddress     = ownerAddress;
            transfer.Amount        = ToFactoredPrice(initialSupply, decimals);
            transfer.TransactionId = GenerateTransactionId(transfer);
            transactions.Add(transfer);

            ApplicationState.PendingRecordsAddRange(transactions);

            //Create genesis block
            var header = CreateBlockHeader(true);
            var block  = CreateBlockAndClearPendingTx(header);

            //Push genesis block to blockchain
            database.SaveBlock(block);

            //Update index
            IndexServices indexServices = new IndexServices();

            indexServices.UpdateIndex(block);
        }
        protected virtual void BeforeProcess(TParameter p, TData d)
        {
            //获取请求的资源和参数
            ResourceManage rema = new ResourceManage();

            p.SetValue(ParameterKey.RESOURCE_MANAGER, rema);
            var defaulttoken = TransactionToken.NewToken();

            p.TransTokenList.Add(defaulttoken);
            p.SetValue(ParameterKey.TOKEN, defaulttoken);
            p.RequestUri         = new Uri($"{p.CurrentHttpContext.Request.Scheme}://{p.CurrentHttpContext.Request.Host}{p.CurrentHttpContext.Request.Path}{p.CurrentHttpContext.Request.QueryString}");
            p.RequestRoute       = p.CurrentHttpContext.Request.Path.Value;
            p.RestResourcesArray = p.CurrentHttpContext.Request.Path.Value.Split('/');

            ProcessRequestInfo(p, d);
            ProcessRequestHeader(p, d);
        }
Exemplo n.º 24
0
        protected virtual void Init(WP p, WD d)
        {
            //获取请求的资源和参数
            ResourceManage rema = new ResourceManage();

            p.SetValue <ResourceManage>(ParameterKey.RESOURCE_MANAGER, rema);
            p.SetValue <TransactionToken>(ParameterKey.TOKEN, TransactionToken.NewToken());
            if (p.ExtentionObj.args != null)
            {
                if (p.ExtentionObj.args.Length > 0)
                {
                    string   reqstr = ComFunc.nvl(p.ExtentionObj.args[0]);
                    string[] arr    = reqstr.Split('.');
                    p[ParameterKey.LOGIC]  = arr[0];
                    p[ParameterKey.ACTION] = arr.Length > 1 ? arr[1] : "";
                }
            }
        }
        public async Task <ResponseDeliverTx> DeliverTx(TransactionToken transactionToken, CreateNumber payload, RequestDeliverTx request, ServerCallContext context)
        {
            if (!IsVerifiedCaller(transactionToken))
            {
                return(ResponseHelper.Deliver.Unauthorized());
            }

            _logger.LogInformation("Received valid DeliverTx request");

            await _callNumberRepository.Add(new CallNumber()
            {
                Owner       = payload.Owner,
                PhoneNumber = payload.PhoneNumber
            });

            _logger.LogInformation("DeliverTx Result: ok");
            return(ResponseHelper.Deliver.Ok());
        }
Exemplo n.º 26
0
        public async Task <ResponseDeliverTx> DeliverTx(TransactionToken transactionToken, RequestTransfer payload, RequestDeliverTx request, ServerCallContext context)
        {
            if (!IsVerifiedCaller(transactionToken, payload.NewOwner))
            {
                return(ResponseHelper.Deliver.Unauthorized());
            }

            _logger.LogInformation("Received valid CheckTx request");

            var callNumber = await _callNumberRepository.Get(payload.PhoneNumber);

            callNumber.TransferRequestStarted = payload.TransferStarted;
            callNumber.TransferRequestedTo    = payload.NewOwner;

            await _callNumberRepository.Update(callNumber);

            _logger.LogInformation($"DeliverTx Result: ok, transfer started: {callNumber.TransferRequestStarted}, to: {callNumber.TransferRequestedTo}");
            return(ResponseHelper.Deliver.Ok());
        }
        protected virtual void BeforeProcess(TParameter p, TData d)
        {
            //获取请求的资源和参数
            ResourceManage rema = new ResourceManage();

            p.SetValue(ParameterKey.RESOURCE_MANAGER, rema);
            var defaulttoken = TransactionToken.NewToken();

            p.TransTokenList.Add(defaulttoken);
            p.SetValue(ParameterKey.TOKEN, defaulttoken);
            p.SetValue("IsAjaxAsync", IsAjaxAsync);
            p.RequestUri = new Uri($"{p.CurrentHttpContext.Request.Scheme}://{p.CurrentHttpContext.Request.Host}{p.CurrentHttpContext.Request.Path}{(p.CurrentHttpContext.Request.QueryString.Value)}");
            GlobalCommon.Logger.WriteLog(LoggerLevel.DEBUG, $"excute request URI:{CurrentContext.Request.Method} \"{p.RequestUri}\"");

            ProcessRequestPath(p, d);
            ProcessRequestHeader(p, d);
            ProcessRequestInfo(p, d);
            ProcessRequestSession(p, d);
            ProcessRequestCookie(p, d);
            ////hostview的引擎
            //p.ExtentionObj.hostviewengine = new HostJsView();
        }
Exemplo n.º 28
0
        public void RollbackTransaction(TransactionToken token)
        {
            if (token.IsExpired)
            {
                throw new Exception("当前Token已经过期,无法使用事务");
            }

            if (token.CurrentStatus == TransactionToken.TransStatus.Begin)
            {
                if (_transd.ContainsKey(token.UniqueID))
                {
                    foreach (IResourceEntity e in _transd[token.UniqueID].Values)
                    {
                        if (e is ITransaction)
                        {
                            ((ITransaction)e).RollbackTransaction();
                        }
                    }
                }
                token.RollBack();
            }
        }
Exemplo n.º 29
0
        public void AddToIndex(TransactionToken record)
        {
            if (record == null)
            {
                return;
            }

            var tokenIndex = new TokenIndexItem()
            {
                Name     = record.Name,
                Symbol   = record.Symbol,
                Decimals = record.Decimals
            };

            database.SaveTokenIndex(tokenIndex);
            IndexTokenCache.AddOrUpdate(tokenIndex);

            //Update key map
            List <string> symbols = database.GetKeyMap("token");

            if (symbols == null)
            {
                //First token in block is native
                database.SaveNativeTokenIndex(tokenIndex);

                symbols = new List <string>();
                symbols.Add(record.Symbol);
                database.SaveKeyMap("token", symbols);
            }
            else
            {
                if (!symbols.Contains(record.Symbol))
                {
                    symbols.Add(record.Symbol);
                    database.SaveKeyMap("token", symbols);
                }
            }
        }
Exemplo n.º 30
0
        protected virtual void Init(HttpContext context, WP p, WD d)
        {
            //获取请求的资源和参数
            ResourceManage rema = new ResourceManage();

            p.SetValue <ResourceManage>(ParameterKey.RESOURCE_MANAGER, rema);
            var defaulttoken = TransactionToken.NewToken();

            p.TransTokenList.Add(defaulttoken);
            p.SetValue <TransactionToken>(ParameterKey.TOKEN, defaulttoken);
            p.SetValue("IsAjaxAsync", IsAjaxAsync);
            //设置serverinfo
            p[DomainKey.APPLICATION_ENVIRONMENT, "server_servername"] = context.Server.MachineName;
            p[DomainKey.APPLICATION_ENVIRONMENT, "serverinfo_ip"]     = context.Request.ServerVariables["LOCAl_ADDR"];
            //设置clientinfo
            var ip = "";

            if (context.Request.ServerVariables["HTTP_VIA"] != null)          // using proxy
            {
                ip = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; // Return real client IP.
            }
            else// not using proxy or can't get the Client IP
            {
                ip = context.Request.ServerVariables["REMOTE_ADDR"]; //While it can't get the Client IP, it will return proxy IP.
            }
            p[DomainKey.APPLICATION_ENVIRONMENT, "clientinfo_ip"]             = ip;
            p[DomainKey.APPLICATION_ENVIRONMENT, "clientinfo_browserversion"] = context.Request.Browser.Version;
            p[DomainKey.APPLICATION_ENVIRONMENT, "clientinfo_platform"]       = context.Request.Browser.Platform;
            p[DomainKey.APPLICATION_ENVIRONMENT, "clientinfo_userhostname"]   = context.Request.UserHostName;
            p.IsNeedSessionAbandon = false;
            p.IsWebSocket          = context.IsWebSocketRequest;
            //hostview的引擎
            p.ExtentionObj.hostviewengine = new HostJsView();
            lock (lockobj)
            {
                Prepare(context, ref p, ref d);
            }
        }