public override async Task <TransactionBlock> BrokerOpsAsync(DagSystem sys, SendTransferBlock send) { var pool = await sys.Storage.GetPoolAsync(send.Tags["token0"], send.Tags["token1"]); if (pool != null) { return(null); } // get token gensis to make the token name proper var token0Gen = await sys.Storage.FindTokenGenesisBlockAsync(null, send.Tags["token0"]); var token1Gen = await sys.Storage.FindTokenGenesisBlockAsync(null, send.Tags["token1"]); //if (token0Gen == null || token1Gen == null) //{ // return; //} var arrStr = new[] { token0Gen.Ticker, token1Gen.Ticker }; Array.Sort(arrStr); var poole = await sys.Storage.GetPoolAsync(arrStr[0], arrStr[1]); if (poole != null) { return(null); } var sb = await sys.Storage.GetLastServiceBlockAsync(); // create a semi random account for pool. // it can be verified by other nodes. var keyStr = $"{send.Hash.Substring(0, 16)},{arrStr[0]},{arrStr[1]},{send.AccountID}"; var AccountId = Base58Encoding.EncodeAccountId(Encoding.ASCII.GetBytes(keyStr).Take(64).ToArray()); var poolGenesis = new PoolGenesisBlock { Height = 1, AccountType = AccountTypes.Pool, AccountID = AccountId, // in fact we not use this account. Balances = new Dictionary <string, long>(), PreviousHash = sb.Hash, ServiceHash = sb.Hash, Fee = 0, FeeCode = LyraGlobal.OFFICIALTICKERCODE, FeeType = AuthorizationFeeTypes.NoFee, // pool specified config Token0 = arrStr[0], Token1 = arrStr[1], RelatedTx = send.Hash }; poolGenesis.AddTag(Block.MANAGEDTAG, ""); // value is always ignored // pool blocks are service block so all service block signed by leader node poolGenesis.InitializeBlock(null, NodeService.Dag.PosWallet.PrivateKey, AccountId: NodeService.Dag.PosWallet.AccountId); return(poolGenesis); //await QueueTxActionBlockAsync(poolGenesis); }
public override async Task <TransactionBlock> BrokerOpsAsync(DagSystem sys, SendTransferBlock sendBlock) { // assume all send variables are legal // token0/1, amount, etc. var blocks = await sys.Storage.FindBlocksByRelatedTxAsync(sendBlock.Hash); if (blocks.Any(a => a is PoolSwapInBlock)) { return(null); } var lsb = await sys.Storage.GetLastServiceBlockAsync(); var swapInBlock = new PoolSwapInBlock { AccountID = sendBlock.DestinationAccountId, VoteFor = null, ServiceHash = lsb.Hash, SourceHash = sendBlock.Hash, Balances = new Dictionary <string, long>(), Fee = 0, FeeCode = LyraGlobal.OFFICIALTICKERCODE, FeeType = AuthorizationFeeTypes.NoFee, RelatedTx = sendBlock.Hash }; swapInBlock.AddTag(Block.MANAGEDTAG, ""); // value is always ignored TransactionBlock prevSend = await sys.Storage.FindBlockByHashAsync(sendBlock.PreviousHash) as TransactionBlock; var txInfo = sendBlock.GetBalanceChanges(prevSend); TransactionBlock latestPoolBlock = await sys.Storage.FindLatestBlockAsync(sendBlock.DestinationAccountId) as TransactionBlock; PoolGenesisBlock poolGenesis = await sys.Storage.FindFirstBlockAsync(latestPoolBlock.AccountID) as PoolGenesisBlock; var depositBalance = new Dictionary <string, decimal>(); if (latestPoolBlock.Balances.Any()) { var lastBalance = latestPoolBlock.Balances.ToDecimalDict(); // the rito must be preserved for every deposition //var poolRito = lastBalance[poolGenesis.Token0] / lastBalance[poolGenesis.Token1]; foreach (var oldBalance in lastBalance) { if (txInfo.Changes.ContainsKey(oldBalance.Key)) { depositBalance.Add(oldBalance.Key, oldBalance.Value + txInfo.Changes[oldBalance.Key]); } else { depositBalance.Add(oldBalance.Key, oldBalance.Value); } } var prevBalance = lastBalance[poolGenesis.Token0]; var curBalance = depositBalance[poolGenesis.Token0]; } else { foreach (var token in txInfo.Changes) { depositBalance.Add(token.Key, token.Value); } } swapInBlock.Balances = depositBalance.ToLongDict(); swapInBlock.Shares = (latestPoolBlock as IPool).Shares; await swapInBlock.InitializeBlockAsync(latestPoolBlock, (hash) => Task.FromResult(Signatures.GetSignature(sys.PosWallet.PrivateKey, hash, sys.PosWallet.AccountId))); return(swapInBlock); }