public override async Task <APIResultCodes> PreSendAuthAsync(DagSystem sys, SendTransferBlock block, TransactionBlock lastBlock) { if (block.Tags.Count != 2 || !block.Tags.ContainsKey("poolid")) { return(APIResultCodes.InvalidBlockTags); } var poolGenesis = sys.Storage.GetPoolByID(block.Tags["poolid"]); if (poolGenesis == null) { return(APIResultCodes.PoolNotExists); } var chgs = block.GetBalanceChanges(lastBlock); if (chgs.Changes[LyraGlobal.OFFICIALTICKERCODE] != 1m) { return(APIResultCodes.InvalidFeeAmount); } if (!(await sys.Storage.FindLatestBlockAsync(poolGenesis.AccountID) is IPool pool)) { return(APIResultCodes.PoolNotExists); } if (!pool.Shares.ContainsKey(block.AccountID)) { return(APIResultCodes.PoolShareNotExists); } return(APIResultCodes.Success); }
async Task <TransactionBlock> MainAsync(DagSystem sys, SendTransferBlock send) { // check exists var daoid = send.Tags["daoid"]; var prevBlock = await sys.Storage.FindLatestBlockAsync(daoid) as TransactionBlock; var txInfo = send.GetBalanceChanges(await sys.Storage.FindBlockByHashAsync(send.PreviousHash) as TransactionBlock); var lsb = await sys.Storage.GetLastServiceBlockAsync(); return(await TransactionOperateAsync(sys, send.Hash, prevBlock, () => prevBlock.GenInc <DaoSendBlock>(), (b) => { // send (b as SendTransferBlock).DestinationAccountId = send.AccountID; // treasure change var curBalance = b.Balances.ToDecimalDict(); var curShares = (b as IDao).Treasure.ToDecimalDict(); curBalance["LYR"] -= curShares[send.AccountID]; curShares.Remove(send.AccountID); b.Balances = curBalance.ToLongDict(); (b as IDao).Treasure = curShares.ToLongDict(); })); }
public override async Task <APIResultCodes> PreSendAuthAsync(DagSystem sys, SendTransferBlock send, TransactionBlock last) { if (send.Tags.Count != 3 || !send.Tags.ContainsKey("daoid") || !send.Tags.ContainsKey("orderid") || string.IsNullOrWhiteSpace(send.Tags["orderid"]) ) { return(APIResultCodes.InvalidBlockTags); } var daoid = send.Tags["daoid"]; var orderid = send.Tags["orderid"]; var daoblk = await sys.Storage.FindLatestBlockAsync(daoid); var orderblk = await sys.Storage.FindLatestBlockAsync(orderid); var ordertx = orderblk as TransactionBlock; // need some balance to close. old bug if (!ordertx.Balances.Any(a => a.Value > 0)) { return(APIResultCodes.InsufficientFunds); } if (daoblk == null || orderblk == null || (orderblk as IOtcOrder).Order.daoId != (daoblk as TransactionBlock).AccountID) { return(APIResultCodes.InvalidTrade); } if ((orderblk as IBrokerAccount).OwnerAccountId != send.AccountID) { return(APIResultCodes.NotSellerOfTrade); } if ((orderblk as IOtcOrder).OOStatus != OTCOrderStatus.Open && (orderblk as IOtcOrder).OOStatus != OTCOrderStatus.Partial && (orderblk as IOtcOrder).OOStatus != OTCOrderStatus.Delist) { return(APIResultCodes.InvalidOrderStatus); } var trades = await sys.Storage.FindOtcTradeForOrderAsync(orderid); if (trades.Any()) { var opened = trades.Cast <IOtcTrade>() .Where(a => a.OTStatus != OTCTradeStatus.Canceled && a.OTStatus != OTCTradeStatus.Closed && a.OTStatus != OTCTradeStatus.DisputeClosed && a.OTStatus != OTCTradeStatus.CryptoReleased ); if (opened.Any()) { return(APIResultCodes.TradesPending); } } return(APIResultCodes.Success); }
public override async Task <APIResultCodes> PreSendAuthAsync(DagSystem sys, SendTransferBlock send, TransactionBlock last) { if (send.Tags.Count != 2 || !send.Tags.ContainsKey("daoid") || string.IsNullOrWhiteSpace(send.Tags["daoid"]) ) { return(APIResultCodes.InvalidBlockTags); } // dao must exists var dao = await sys.Storage.FindLatestBlockAsync(send.Tags["daoid"]); if (dao == null) { return(APIResultCodes.InvalidDAO); } // invest must exists if (!(dao as IDao).Treasure.ContainsKey(send.AccountID)) { return(APIResultCodes.AccountDoesNotExist); } return(APIResultCodes.Success); }
protected async Task <TransactionBlock> ChangeStateAsync(DagSystem sys, SendTransferBlock send) { var blocks = await sys.Storage.FindBlocksByRelatedTxAsync(send.Hash); var txInfo = send.GetBalanceChanges(await sys.Storage.FindBlockByHashAsync(send.PreviousHash) as TransactionBlock); var prevBlock = await sys.Storage.FindLatestBlockAsync(send.DestinationAccountId) as TransactionBlock; var votblk = await TransactionOperateAsync(sys, send.Hash, prevBlock, () => prevBlock.GenInc <OtcTradeRecvBlock>(), (b) => { // recv (b as ReceiveTransferBlock).SourceHash = send.Hash; // broker (b as IBrokerAccount).RelatedTx = send.Hash; // trade (b as IOtcTrade).OTStatus = OTCTradeStatus.Dispute; var oldbalance = prevBlock.Balances.ToDecimalDict(); if (oldbalance.ContainsKey("LYR")) { oldbalance["LYR"] += txInfo.Changes["LYR"]; } else { oldbalance.Add("LYR", txInfo.Changes["LYR"]); } b.Balances = oldbalance.ToLongDict(); }); return(votblk); }
// user pay via off-chain ways and confirm payment in OTC trade. public override async Task <APIResultCodes> PreSendAuthAsync(DagSystem sys, SendTransferBlock send, TransactionBlock last) { if (send.Tags.Count != 1) { return(APIResultCodes.InvalidBlockTags); } var tradeid = send.DestinationAccountId; var tradeblk = await sys.Storage.FindLatestBlockAsync(tradeid); if (tradeblk == null || tradeblk is not IOtcTrade) { return(APIResultCodes.InvalidTrade); } if ((tradeblk as IBrokerAccount).OwnerAccountId != send.AccountID && (tradeblk as IOtcTrade).Trade.orderOwnerId != send.AccountID ) { return(APIResultCodes.NotOwnerOfTrade); } // can't reopen closed dispute trade if ((tradeblk as IOtcTrade).OTStatus == OTCTradeStatus.Dispute || (tradeblk as IOtcTrade).OTStatus == OTCTradeStatus.DisputeClosed) { return(APIResultCodes.InvalidTradeStatus); } return(APIResultCodes.Success); }
public override async Task <APIResultCodes> PreSendAuthAsync(DagSystem sys, SendTransferBlock block, TransactionBlock lastBlock) { var chgs = block.GetBalanceChanges(lastBlock); if (!chgs.Changes.ContainsKey(LyraGlobal.OFFICIALTICKERCODE)) { return(APIResultCodes.InvalidFeeAmount); } if (block.Tags.Count == 1) { // verify sender is the owner of stkingblock var stks = await sys.Storage.FindAllStakingAccountForOwnerAsync(block.AccountID); if (!stks.Any(a => a.AccountID == block.DestinationAccountId)) { return(APIResultCodes.InvalidStakingAccount); } } else { return(APIResultCodes.InvalidBlockTags); } return(APIResultCodes.Success); }
protected async Task <TransactionBlock> SlashCollateral(DagSystem sys, SendTransferBlock send, string to, decimal amount) { var blocks = await sys.Storage.FindBlocksByRelatedTxAsync(send.Hash); var resolv = JsonConvert.DeserializeObject <ODRResolution>(send.Tags["data"]); var tradelatest = await sys.Storage.FindLatestBlockAsync(resolv.tradeid) as IOtcTrade; var daolatest = await sys.Storage.FindLatestBlockAsync(tradelatest.Trade.daoId) as TransactionBlock; var daosendblk = await TransactionOperateAsync(sys, send.Hash, daolatest, () => daolatest.GenInc <DaoSendBlock>(), (b) => { // send (b as SendTransferBlock).DestinationAccountId = to; // broker (b as IBrokerAccount).RelatedTx = send.Hash; var oldbalance = daolatest.Balances.ToDecimalDict(); oldbalance["LYR"] -= amount; b.Balances = oldbalance.ToLongDict(); }); return(daosendblk); }
public override async Task <APIResultCodes> PreSendAuthAsync(DagSystem sys, SendTransferBlock block, TransactionBlock last) { var dexid4 = block.Tags.ContainsKey("dexid") ? block.Tags["dexid"] : null; if (dexid4 == null) { return(APIResultCodes.InvalidAccountId); } decimal wdwmount4 = 0; var wdwamountstr4 = block.Tags.ContainsKey("amount") ? block.Tags["amount"] : null; if (wdwamountstr4 == null || !decimal.TryParse(wdwamountstr4, out wdwmount4) || wdwmount4 <= 0) { return(APIResultCodes.InvalidAmount); } // verify owner var lb4 = await sys.Storage.FindLatestBlockAsync(dexid4) as IBrokerAccount; if (lb4 == null || block.AccountID != lb4.OwnerAccountId) { return(APIResultCodes.InvalidAccountId); } var extaddr = block.Tags.ContainsKey("extaddr") ? block.Tags["extaddr"] : null; if (string.IsNullOrWhiteSpace(extaddr)) { return(APIResultCodes.InvalidExternalAddress); } return(APIResultCodes.Success); }
public override async Task <APIResultCodes> PreSendAuthAsync(DagSystem sys, SendTransferBlock block, TransactionBlock lastBlock) { var chgs = block.GetBalanceChanges(lastBlock); if (!chgs.Changes.ContainsKey(LyraGlobal.OFFICIALTICKERCODE)) { return(APIResultCodes.InvalidFeeAmount); } var pftid = block.Tags.ContainsKey("pftid") ? block.Tags["pftid"] : null; if (pftid == null) { return(APIResultCodes.InvalidAccountId); } var pft = await sys.Storage.FindFirstBlockAsync(pftid) as ProfitingGenesis; if (pft == null) { return(APIResultCodes.InvalidAccountId); } var stkrs = sys.Storage.FindAllStakings(pftid, DateTime.UtcNow); if (!stkrs.Any(a => a.OwnerAccount == block.AccountID) && pft.OwnerAccountId != block.AccountID) { return(APIResultCodes.RequestNotPermited); } return(APIResultCodes.Success); }
public override async Task <APIResultCodes> PreSendAuthAsync(DagSystem sys, SendTransferBlock block, TransactionBlock last) { var dexid = block.Tags.ContainsKey("dexid") ? block.Tags["dexid"] : null; if (dexid == null) { return(APIResultCodes.InvalidAccountId); } decimal mintamount = 0; var mintamountstr = block.Tags.ContainsKey("amount") ? block.Tags["amount"] : null; if (mintamountstr == null || !decimal.TryParse(mintamountstr, out mintamount) || mintamount <= 0) { return(APIResultCodes.InvalidAmount); } // verify if sender is dex server if (block.AccountID != LyraGlobal.GetDexServerAccountID(LyraNodeConfig.GetNetworkId())) { return(APIResultCodes.InvalidDexServer); } // verify dex wallet owner var brkr = await sys.Storage.FindLatestBlockAsync(dexid) as IBrokerAccount; if (brkr == null) { return(APIResultCodes.InvalidBrokerAcount); } return(APIResultCodes.Success); }
public Task <NewTransferAPIResult> LookForNewTransfer(string AccountId, string Signature) { NewTransferAPIResult transfer_info = new NewTransferAPIResult(); try { SendTransferBlock sendBlock = BlockChain.Singleton.FindUnsettledSendBlock(AccountId); if (sendBlock != null) { TransactionBlock previousBlock = BlockChain.Singleton.FindBlockByHash(sendBlock.PreviousHash); if (previousBlock == null) { transfer_info.ResultCode = APIResultCodes.CouldNotTraceSendBlockChain; } else { transfer_info.Transfer = sendBlock.GetTransaction(previousBlock); //CalculateTransaction(sendBlock, previousSendBlock); transfer_info.SourceHash = sendBlock.Hash; transfer_info.NonFungibleToken = sendBlock.NonFungibleToken; transfer_info.ResultCode = APIResultCodes.Success; } } else { transfer_info.ResultCode = APIResultCodes.NoNewTransferFound; } } catch (Exception e) { transfer_info.ResultCode = APIResultCodes.UnknownError; } return(Task.FromResult(transfer_info)); }
async Task <TransactionBlock> SealTradeAsync(DagSystem sys, SendTransferBlock send) { var tradeid = send.Tags["tradeid"]; var lastblock = await sys.Storage.FindLatestBlockAsync(tradeid) as TransactionBlock; var txInfo = send.GetBalanceChanges(await sys.Storage.FindBlockByHashAsync(send.PreviousHash) as TransactionBlock); var sb = await sys.Storage.GetLastServiceBlockAsync(); return(await TransactionOperateAsync(sys, send.Hash, lastblock, () => lastblock.GenInc <OtcTradeRecvBlock>(), (b) => { // recv (b as ReceiveTransferBlock).SourceHash = send.Hash; // broker (b as IBrokerAccount).RelatedTx = send.Hash; // balance var oldbalance = b.Balances.ToDecimalDict(); if (oldbalance.ContainsKey("LYR")) { oldbalance["LYR"] += txInfo.Changes["LYR"]; } else { oldbalance.Add("LYR", txInfo.Changes["LYR"]); } b.Balances = oldbalance.ToLongDict(); // Trade status (b as IOtcTrade).OTStatus = OTCTradeStatus.Canceled; })); }
// user pay via off-chain ways and confirm payment in OTC trade. public override async Task <APIResultCodes> PreSendAuthAsync(DagSystem sys, SendTransferBlock send, TransactionBlock last) { if (send.Tags.Count != 2 || !send.Tags.ContainsKey("tradeid") || string.IsNullOrWhiteSpace(send.Tags["tradeid"])) { return(APIResultCodes.InvalidBlockTags); } var tradeid = send.Tags["tradeid"]; var tradeblk = await sys.Storage.FindLatestBlockAsync(tradeid); if (tradeblk == null) { return(APIResultCodes.InvalidTrade); } if ((tradeblk as IBrokerAccount).OwnerAccountId != send.AccountID) { return(APIResultCodes.NotOwnerOfTrade); } if ((tradeblk as IOtcTrade).OTStatus != OTCTradeStatus.Open) { return(APIResultCodes.InvalidTradeStatus); } return(APIResultCodes.Success); }
protected Task <TransactionBlock> ChangeStateAsync(DagSystem sys, SendTransferBlock sendBlock) { return(TradeBlockOperateAsync(sys, sendBlock, () => new OtcTradeRecvBlock(), (b) => { var txInfo = sendBlock.GetBalanceChanges(sys.Storage.FindBlockByHash(sendBlock.PreviousHash) as TransactionBlock); var recvBalances = b.Balances.ToDecimalDict(); foreach (var chg in txInfo.Changes) { if (recvBalances.ContainsKey(chg.Key)) { recvBalances[chg.Key] += chg.Value; } else { recvBalances.Add(chg.Key, chg.Value); } } b.Balances = recvBalances.ToLongDict(); (b as IOtcTrade).OTStatus = OTCTradeStatus.FiatReceived; })); }
private async Task <TransactionBlock> GetBlocksAsync(DagSystem sys, SendTransferBlock send) { var blocks = await sys.Storage.FindBlocksByRelatedTxAsync(send.Hash); var resolv = JsonConvert.DeserializeObject <ODRResolution>(send.Tags["data"]); if (blocks.Count < resolv.actions.Length + 1) { // populate tos var tradegen = await sys.Storage.FindFirstBlockAsync(resolv.tradeid) as IOtcTrade; var tos = new Dictionary <Parties, string> { { Parties.Seller, tradegen.Trade.orderOwnerId }, { Parties.Buyer, (tradegen as IBrokerAccount).OwnerAccountId }, { Parties.DAOTreasure, (tradegen as TransactionBlock).AccountID } }; return(await SlashCollateral(sys, send, tos[resolv.actions[blocks.Count - 1].to], resolv.actions[blocks.Count - 1].amount)); } else { return(null); } }
// DEX #region BRK_DEX_DPOREQ public override async Task <APIResultCodes> PreSendAuthAsync(DagSystem sys, SendTransferBlock block, TransactionBlock last) { var symbol = block.Tags.ContainsKey("symbol") ? block.Tags["symbol"] : null; if (symbol == null) { return(APIResultCodes.InvalidName); } var provider = block.Tags.ContainsKey("provider") ? block.Tags["provider"] : null; if (provider == null) { return(APIResultCodes.InvalidName); } if (block.Tags.Count > 3) { return(APIResultCodes.InvalidBlockTags); } var dc = new DexClient(LyraNodeConfig.GetNetworkId()); var asts = await dc.GetSupportedExtTokenAsync(LyraNodeConfig.GetNetworkId()); var ast = asts.Asserts.Where(a => a.Symbol == symbol && a.NetworkProvider == provider) .FirstOrDefault(); if (ast == null) { return(APIResultCodes.InvalidExternalToken); } return(APIResultCodes.Success); }
public override async Task <APIResultCodes> PreSendAuthAsync(DagSystem sys, SendTransferBlock block, TransactionBlock last) { var dexid3 = block.Tags.ContainsKey("dexid") ? block.Tags["dexid"] : null; if (dexid3 == null) { return(APIResultCodes.InvalidAccountId); } // verify owner var lb3 = await sys.Storage.FindLatestBlockAsync(dexid3) as IDexWallet; if (lb3 == null || block.AccountID != lb3.OwnerAccountId) { return(APIResultCodes.InvalidAccountId); } var tickerp = $"tether/{lb3.ExtSymbol}"; var userlb = await sys.Storage.FindLatestBlockAsync(block.AccountID) as TransactionBlock; if (userlb == null || !userlb.Balances.ContainsKey(tickerp)) { return(APIResultCodes.InvalidAmount); } return(APIResultCodes.Success); }
public override async Task <APIResultCodes> PreSendAuthAsync(DagSystem sys, SendTransferBlock send, TransactionBlock last) { if (send.Tags.Count != 2 || !send.Tags.ContainsKey("daoid") || string.IsNullOrWhiteSpace(send.Tags["daoid"]) ) { return(APIResultCodes.InvalidBlockTags); } // dao must exists var dao = await sys.Storage.FindLatestBlockAsync(send.Tags["daoid"]); if (dao == null) { return(APIResultCodes.InvalidDAO); } var txInfo = send.GetBalanceChanges(await sys.Storage.FindBlockByHashAsync(send.PreviousHash) as TransactionBlock); if (txInfo.Changes.Count != 1 || !txInfo.Changes.ContainsKey("LYR")) { return(APIResultCodes.InvalidToken); } //min amount to invest var amount = txInfo.Changes["LYR"]; if (amount < 10000) { return(APIResultCodes.InvalidAmount); } return(APIResultCodes.Success); }
async Task <TransactionBlock> SendTokenFromTradeToOrderAsync(DagSystem sys, SendTransferBlock send) { var tradeid = send.Tags["tradeid"]; var lastblock = await sys.Storage.FindLatestBlockAsync(tradeid) as TransactionBlock; var txInfo = send.GetBalanceChanges(await sys.Storage.FindBlockByHashAsync(send.PreviousHash) as TransactionBlock); var sb = await sys.Storage.GetLastServiceBlockAsync(); return(await TransactionOperateAsync(sys, send.Hash, lastblock, () => lastblock.GenInc <OtcTradeSendBlock>(), (b) => { // send (b as SendTransferBlock).DestinationAccountId = (lastblock as IOtcTrade).Trade.orderId; // broker (b as IBrokerAccount).RelatedTx = send.Hash; // balance var oldbalance = b.Balances.ToDecimalDict(); foreach (var key in b.Balances.Keys) { oldbalance[key] = 0; } b.Balances = oldbalance.ToLongDict(); })); }
public override async Task <APIResultCodes> PreSendAuthAsync(DagSystem sys, SendTransferBlock send, TransactionBlock last) { if (send.Tags.Count != 3 || !send.Tags.ContainsKey("daoid") || !send.Tags.ContainsKey("orderid") || string.IsNullOrWhiteSpace(send.Tags["orderid"]) ) { return(APIResultCodes.InvalidBlockTags); } var daoid = send.Tags["daoid"]; var orderid = send.Tags["orderid"]; var daoblk = await sys.Storage.FindLatestBlockAsync(daoid); var orderblk = await sys.Storage.FindLatestBlockAsync(orderid); if (daoblk == null || orderblk == null || (orderblk as IOtcOrder).Order.daoId != (daoblk as TransactionBlock).AccountID) { return(APIResultCodes.InvalidTrade); } if ((orderblk as IBrokerAccount).OwnerAccountId != send.AccountID) { return(APIResultCodes.NotSellerOfTrade); } if ((orderblk as IOtcOrder).OOStatus != OTCOrderStatus.Partial) { return(APIResultCodes.InvalidOrderStatus); } return(APIResultCodes.Success); }
private static async Task <NewTransferAPIResult2> GetSendToPftAsync(DagSystem sys, string pftid) { Console.WriteLine("CR Dividend: GetSendToPftAsync"); NewTransferAPIResult2 transfer_info = new NewTransferAPIResult2(); SendTransferBlock sendBlock = await sys.Storage.FindUnsettledSendBlockAsync(pftid); if (sendBlock != null) { TransactionBlock previousBlock = await sys.Storage.FindBlockByHashAsync(sendBlock.PreviousHash) as TransactionBlock; if (previousBlock == null) { transfer_info.ResultCode = APIResultCodes.CouldNotTraceSendBlockChain; } else { transfer_info.Transfer = sendBlock.GetBalanceChanges(previousBlock); //CalculateTransaction(sendBlock, previousSendBlock); transfer_info.SourceHash = sendBlock.Hash; transfer_info.NonFungibleToken = sendBlock.NonFungibleToken; transfer_info.ResultCode = APIResultCodes.Success; } } else { transfer_info.ResultCode = APIResultCodes.NoNewTransferFound; } return(transfer_info); }
public async Task <TransactionBlock> GenesisAsync(DagSystem sys, SendTransferBlock send) { var name = send.Tags["name"]; var desc = send.Tags["desc"]; var sellerPar = int.Parse(send.Tags["sellerPar"]); var buyerPar = int.Parse(send.Tags["buyerPar"]); // create a semi random account for pool. // it can be verified by other nodes. var keyStr = $"{send.Hash.Substring(0, 16)},{name},{send.AccountID}"; var AccountId = Base58Encoding.EncodeAccountId(Encoding.ASCII.GetBytes(keyStr).Take(64).ToArray()); var exists = await sys.Storage.FindFirstBlockAsync(AccountId); if (exists != null) { return(null); } var sb = await sys.Storage.GetLastServiceBlockAsync(); var daogen = new DaoGenesisBlock { Height = 1, ServiceHash = sb.Hash, Fee = 0, FeeCode = LyraGlobal.OFFICIALTICKERCODE, FeeType = AuthorizationFeeTypes.NoFee, // transaction AccountType = AccountTypes.DAO, AccountID = AccountId, Balances = new Dictionary <string, long>(), // broker Name = name, OwnerAccountId = send.AccountID, RelatedTx = send.Hash, // profiting PType = ProfitingType.Orgnization, ShareRito = decimal.Parse(send.Tags["share"]), Seats = int.Parse(send.Tags["seats"]), SellerFeeRatio = decimal.Parse(send.Tags["sellerFeeRatio"]), BuyerFeeRatio = decimal.Parse(send.Tags["buyerFeeRatio"]), // dao Description = desc, SellerPar = sellerPar, BuyerPar = buyerPar, Treasure = new Dictionary <string, long>(), }; daogen.AddTag(Block.MANAGEDTAG, ""); // value is always ignored // pool blocks are service block so all service block signed by leader node daogen.InitializeBlock(null, NodeService.Dag.PosWallet.PrivateKey, AccountId: NodeService.Dag.PosWallet.AccountId); return(daogen); }
public async Task <AuthorizationAPIResult> SendTransferAsync(SendTransferBlock sendBlock) { if (!CheckServiceStatus()) { return(null); } return(await _trans.SendTransferAsync(sendBlock)); }
public async Task <AuthorizationAPIResult> SendTransfer(SendTransferBlock sendBlock) { return(await Pre_PrepareAsync(sendBlock, async (b) => { var feeResult = await ProcessTransferFee(b as SendTransferBlock); return feeResult.block; }).ConfigureAwait(false)); }
async Task <TransactionBlock> DelistOrderAsync(DagSystem sys, SendTransferBlock send) { var daoid = send.Tags["daoid"]; var orderid = send.Tags["orderid"]; var lastblock = await sys.Storage.FindLatestBlockAsync(orderid) as TransactionBlock; var order = (lastblock as IOtcOrder).Order; var sb = await sys.Storage.GetLastServiceBlockAsync(); var sendToTradeBlock = new OtcOrderSendBlock { // block ServiceHash = sb.Hash, // trans Fee = 0, FeeCode = LyraGlobal.OFFICIALTICKERCODE, FeeType = AuthorizationFeeTypes.NoFee, AccountID = lastblock.AccountID, Balances = lastblock.Balances.ToDecimalDict().ToLongDict(), // send DestinationAccountId = (lastblock as IBrokerAccount).OwnerAccountId, // broker Name = ((IBrokerAccount)lastblock).Name, OwnerAccountId = ((IBrokerAccount)lastblock).OwnerAccountId, RelatedTx = send.Hash, // otc Order = new OTCOrder { daoId = ((IOtcOrder)lastblock).Order.daoId, dir = ((IOtcOrder)lastblock).Order.dir, crypto = ((IOtcOrder)lastblock).Order.crypto, fiat = ((IOtcOrder)lastblock).Order.fiat, fiatPrice = ((IOtcOrder)lastblock).Order.fiatPrice, priceType = ((IOtcOrder)lastblock).Order.priceType, price = ((IOtcOrder)lastblock).Order.price, limitMax = ((IOtcOrder)lastblock).Order.limitMax, limitMin = ((IOtcOrder)lastblock).Order.limitMin, payBy = ((IOtcOrder)lastblock).Order.payBy, amount = 0, collateral = ((IOtcOrder)lastblock).Order.collateral, // this is the difference with close. collateralPrice = ((IOtcOrder)lastblock).Order.collateralPrice }, OOStatus = OTCOrderStatus.Delist, }; sendToTradeBlock.Balances[order.crypto] = 0; sendToTradeBlock.AddTag(Block.MANAGEDTAG, ""); // value is always ignored sendToTradeBlock.InitializeBlock(lastblock, NodeService.Dag.PosWallet.PrivateKey, AccountId: NodeService.Dag.PosWallet.AccountId); return(sendToTradeBlock); }
async Task <TransactionBlock> SendTokenFromDaoToOrderAsync(DagSystem sys, SendTransferBlock send) { var order = JsonConvert.DeserializeObject <OTCOrder>(send.Tags["data"]); var lastblock = await sys.Storage.FindLatestBlockAsync(order.daoId) as TransactionBlock; var keyStr = $"{send.Hash.Substring(0, 16)},{order.crypto},{send.AccountID}"; var AccountId = Base58Encoding.EncodeAccountId(Encoding.ASCII.GetBytes(keyStr).Take(64).ToArray()); var sb = await sys.Storage.GetLastServiceBlockAsync(); var sendToOrderBlock = new DaoSendBlock { // block ServiceHash = sb.Hash, // trans Fee = 0, FeeCode = LyraGlobal.OFFICIALTICKERCODE, FeeType = AuthorizationFeeTypes.NoFee, AccountID = lastblock.AccountID, // send DestinationAccountId = AccountId, // broker Name = ((IBrokerAccount)lastblock).Name, OwnerAccountId = ((IBrokerAccount)lastblock).OwnerAccountId, RelatedTx = send.Hash, // profiting PType = ((IProfiting)lastblock).PType, ShareRito = ((IProfiting)lastblock).ShareRito, Seats = ((IProfiting)lastblock).Seats, // dao SellerFeeRatio = ((IDao)lastblock).SellerFeeRatio, BuyerFeeRatio = ((IDao)lastblock).BuyerFeeRatio, SellerPar = ((IDao)lastblock).SellerPar, BuyerPar = ((IDao)lastblock).BuyerPar, Description = ((IDao)lastblock).Description, Treasure = ((IDao)lastblock).Treasure.ToDecimalDict().ToLongDict(), }; // calculate balance var dict = lastblock.Balances.ToDecimalDict(); dict[order.crypto] -= order.amount; dict[LyraGlobal.OFFICIALTICKERCODE] -= 2; // for delist and close use later sendToOrderBlock.Balances = dict.ToLongDict(); sendToOrderBlock.AddTag(Block.MANAGEDTAG, ""); // value is always ignored sendToOrderBlock.InitializeBlock(lastblock, NodeService.Dag.PosWallet.PrivateKey, AccountId: NodeService.Dag.PosWallet.AccountId); return(sendToOrderBlock); }
public override async Task <APIResultCodes> PreSendAuthAsync(DagSystem sys, SendTransferBlock send, TransactionBlock last) { if (send.Tags.Count != 3 || !send.Tags.ContainsKey("voteid") || string.IsNullOrWhiteSpace(send.Tags["voteid"]) || !send.Tags.ContainsKey("index") || string.IsNullOrWhiteSpace(send.Tags["index"]) ) { return(APIResultCodes.InvalidBlockTags); } var voteid = send.Tags["voteid"]; var index = int.Parse(send.Tags["index"]); var voteg = sys.Storage.FindFirstBlock(voteid) as VotingGenesisBlock; var votel = await sys.Storage.FindLatestBlockAsync(voteid); // index must in range if (index < 0 || index > voteg.Subject.Options.Count() - 1) { return(APIResultCodes.InvalidVote); } // voter should in treasure the time when vote generated // we find it by voteg.relatedtx var vgreltx = voteg.RelatedTx; var allreltx = await sys.Storage.FindBlocksByRelatedTxAsync(vgreltx); var dao = await sys.Storage.FindBlockByHashAsync( allreltx.First(a => a is DaoRecvBlock).Hash); if (!(dao as IDao).Treasure.ContainsKey(send.AccountID)) { return(APIResultCodes.Unauthorized); } // voter shouldn't multiple vote for (var a = votel.Height; a > 1; a--) { var vx = await sys.Storage.FindBlockByHeightAsync(voteid, a); if ((vx as VotingBlock).VoterId == send.AccountID) { return(APIResultCodes.InvalidVote); } } // vote should be in progress if ((votel as IVoting).VoteState != VoteStatus.InProgress) { return(APIResultCodes.InvalidVote); } return(APIResultCodes.Success); }
public override async Task <TransactionBlock> BrokerOpsAsync(DagSystem sys, SendTransferBlock send) { var blocks = await sys.Storage.FindBlocksByRelatedTxAsync(send.Hash); if (blocks.Any(a => a is DexSendBlock)) { return(null); } var dexid = send.Tags["dexid"]; var amount = long.Parse(send.Tags["amount"]).ToBalanceDecimal(); var last = await sys.Storage.FindLatestBlockAsync(dexid) as TransactionBlock; var lastdex = last as IDexWallet; var ticker = $"tether/{lastdex.ExtSymbol}"; var gensis = await sys.Storage.FindTokenGenesisBlockAsync(null, ticker); var sb = await sys.Storage.GetLastServiceBlockAsync(); var sendtoken = new DexSendBlock { ServiceHash = sb.Hash, Fee = 0, FeeCode = LyraGlobal.OFFICIALTICKERCODE, FeeType = AuthorizationFeeTypes.NoFee, // transaction AccountID = last.AccountID, // in fact we not use this account. Balances = new Dictionary <string, long>(), // broker Name = lastdex.Name, OwnerAccountId = lastdex.OwnerAccountId, RelatedTx = send.Hash, // Dex wallet IntSymbol = lastdex.IntSymbol, ExtSymbol = lastdex.ExtSymbol, ExtProvider = lastdex.ExtProvider, ExtAddress = lastdex.ExtAddress, // send DestinationAccountId = send.AccountID }; sendtoken.Balances = last.Balances.ToDecimalDict().ToLongDict(); sendtoken.Balances[ticker] -= amount.ToBalanceLong(); sendtoken.AddTag(Block.MANAGEDTAG, ""); // value is always ignored sendtoken.InitializeBlock(last, NodeService.Dag.PosWallet.PrivateKey, AccountId: NodeService.Dag.PosWallet.AccountId); return(sendtoken); }
async Task <AuthorizationAPIResult> INodeAPI.SendTransfer(SendTransferBlock block) { var request = new SendTransferRequest() { SendBlockJson = Json(block) }; var result = await SendTransferAsync(request); return(ToAAR(result)); }