예제 #1
0
        public static string[] AffectedAccounts(Tx tx, Meta meta)
        {
            var accounts = new List <string>();

            accounts.Add(tx.Account);

            if (tx.Destination != null)
            {
                accounts.Add(tx.Destination);
            }

            if (tx.LimitAmount != null)
            {
                accounts.Add(tx.LimitAmount.Issuer);
            }

            if (meta != null && meta.TransactionResult == "tesSUCCESS")
            {
                foreach (var an in meta.AffectedNodes)
                {
                    var node = an.CreatedNode ?? an.DeletedNode ?? an.ModifiedNode;
                    if (node == null)
                    {
                        continue;
                    }

                    var fieldsSet = new FieldsSet(node.FinalFields, node.NewFields, node.PreviousFields);

                    switch (node.LedgerEntryType)
                    {
                    case "AccountRoot":
                    case "Offer":
                        var account = fieldsSet.Account;
                        if (account != null)
                        {
                            accounts.Add(account);
                        }

                        break;

                    case "SkywellState":
                        var highLimit = fieldsSet.HighLimit;
                        if (highLimit != null && highLimit.Issuer != null)
                        {
                            accounts.Add(highLimit.Issuer);
                        }

                        var lowLimit = fieldsSet.LowLimit;
                        if (lowLimit != null && lowLimit.Issuer != null)
                        {
                            accounts.Add(lowLimit.Issuer);
                        }

                        break;
                    }
                }
            }

            return(accounts.ToArray());
        }
예제 #2
0
        public static string[] AffectBooks(Tx tx, Meta meta)
        {
            if (tx == null || meta == null)
            {
                return(null);
            }

            var isSell = ((long)LedgerOfferFlags.Sell & tx.Flags) != 0;
            var books  = new List <string>();

            foreach (var an in meta.AffectedNodes)
            {
                var node = an.CreatedNode ?? an.ModifiedNode ?? an.DeletedNode;
                if (node == null || node.LedgerEntryType != "Offer")
                {
                    continue;
                }

                var fielsSet = new FieldsSet(node.FinalFields, node.NewFields, node.PreviousFields);
                var gets     = fielsSet.TakerGets;
                var pays     = fielsSet.TakerPays;
                var getsKey  = GetAmountString(gets);
                var paysKey  = GetAmountString(pays);
                var key      = isSell ? GetAmoutPairKey(pays, gets) : GetAmoutPairKey(gets, pays);
                books.Add(key);
            }
            return(books.ToArray());
        }
예제 #3
0
        private static NodeEffect[] ParseEffects(Tx tx, AffectedNode[] affectedNodes, string account, TxResult result)
        {
            if (affectedNodes == null || affectedNodes.Length == 0)
            {
                return(null);
            }

            var effects = new List <NodeEffect>();

            foreach (var an in affectedNodes)
            {
                var        diffType   = an.DiffType;
                var        node       = an.CreatedNode ?? an.DeletedNode ?? an.ModifiedNode;
                var        fieldsSet  = new FieldsSet(node.FinalFields, node.PreviousFields, node.NewFields);
                NodeEffect nodeEffect = null;

                //TODO now only get offer related effects, need to process other entry type

                if (node.LedgerEntryType == "Offer")
                {
                    // for new and cancelled offers
                    var         sell        = fieldsSet.Flags == (long)LedgerOfferFlags.Sell;
                    OfferEffect offerEffect = null;

                    // current account offer
                    if (fieldsSet.Account == account)
                    {
                        // 1. offer_partially_funded
                        var seq = fieldsSet.Sequence;
                        if (diffType == DiffType.ModifiedNode || (diffType == DiffType.DeletedNode && node.PreviousFields != null && node.PreviousFields.TakerGets != null && !IsAmountZero(node.FinalFields.TakerGets)))
                        {
                            var partiallyFoundedEffect = new OfferPartiallyFundedEffect();
                            offerEffect = partiallyFoundedEffect;
                            partiallyFoundedEffect.Seq = seq;

                            partiallyFoundedEffect.CounterParty = new CounterParty {
                                Account = tx.Account, Seq = tx.Sequence, Hash = tx.Hash
                            };
                            if (diffType == DiffType.DeletedNode)
                            {
                                partiallyFoundedEffect.Cancelled = true;
                            }
                            else
                            {
                                // TODO no need partially funded must remains offers
                                partiallyFoundedEffect.Remaining = !IsAmountZero(fieldsSet.TakerGets);
                            }

                            var gets = fieldsSet.TakerGets;
                            var pays = fieldsSet.TakerPays;
                            partiallyFoundedEffect.Gets = gets;
                            partiallyFoundedEffect.Pays = pays;
                            partiallyFoundedEffect.Got  = AmountSubtract(node.PreviousFields.TakerPays, pays);
                            partiallyFoundedEffect.Paid = AmountSubtract(node.PreviousFields.TakerGets, gets);
                            partiallyFoundedEffect.Type = sell ? OfferEffectType.Sold : OfferEffectType.Bought;
                        }
                        else
                        {
                            // offer_funded, offer_created or offer_cancelled offer effect
                            var effect = diffType == DiffType.CreatedNode ? EffectType.OfferCreated : (node.PreviousFields != null && node.PreviousFields.TakerPays != null ? EffectType.OfferFunded : EffectType.OfferCancelled);
                            switch (effect)
                            {
                            // 2. offer_funded
                            case EffectType.OfferFunded:
                                var fundedfEffect = new OfferFundedEffect();
                                fundedfEffect.Seq = seq;
                                offerEffect       = fundedfEffect;

                                fundedfEffect.CounterParty = new CounterParty {
                                    Account = tx.Account, Seq = tx.Sequence, Hash = tx.Hash
                                };
                                fundedfEffect.Got  = AmountSubtract(node.PreviousFields.TakerPays, fieldsSet.TakerPays);
                                fundedfEffect.Paid = AmountSubtract(node.PreviousFields.TakerGets, fieldsSet.TakerGets);
                                fundedfEffect.Type = sell ? OfferEffectType.Sold : OfferEffectType.Bought;
                                break;

                            // 3. offer_created
                            case EffectType.OfferCreated:
                                var createdEffect = new OfferCreatedEffect();
                                createdEffect.Seq = seq;
                                offerEffect       = createdEffect;

                                createdEffect.Gets = fieldsSet.TakerGets;
                                createdEffect.Pays = fieldsSet.TakerPays;
                                createdEffect.Type = sell ? OfferEffectType.Sell : OfferEffectType.Buy;
                                break;

                            // 4. offer_cancelled
                            case EffectType.OfferCancelled:
                                var cancelledEffect = new OfferCancelledEffect();
                                cancelledEffect.Seq = seq;
                                offerEffect         = cancelledEffect;

                                cancelledEffect.Gets = fieldsSet.TakerGets;
                                cancelledEffect.Pays = fieldsSet.TakerPays;
                                cancelledEffect.Type = sell ? OfferEffectType.Sell : OfferEffectType.Buy;

                                // collect data for cancel transaction type
                                if (result.Type == TxResultType.OfferCancel)
                                {
                                    var cancelResult = result as OfferCancelTxResult;
                                    cancelResult.Gets = cancelledEffect.Gets;
                                    cancelResult.Pays = cancelledEffect.Pays;
                                }

                                break;
                            }
                        }
                    }
                    // 5. offer_bought
                    else if (tx.Account == account && node.PreviousFields != null)
                    {
                        var boughtEffect = new OfferBoughtEffect();
                        offerEffect = boughtEffect;

                        boughtEffect.CounterParty = new CounterParty {
                            Account = fieldsSet.Account, Seq = fieldsSet.Sequence, Hash = node.PreviousTxnID ?? fieldsSet.PreviousTxnID
                        };
                        boughtEffect.Paid = AmountSubtract(node.PreviousFields.TakerPays, fieldsSet.TakerPays);
                        boughtEffect.Got  = AmountSubtract(node.PreviousFields.TakerGets, fieldsSet.TakerGets);
                        boughtEffect.Type = sell ? OfferEffectType.Bought : OfferEffectType.Sold;
                    }

                    // add price
                    if (offerEffect != null && offerEffect.GotOrPays != null && offerEffect.PaidOrGets != null)
                    {
                        var created          = offerEffect.Effect == EffectType.OfferCreated && offerEffect.Type == OfferEffectType.Buy;
                        var funded           = offerEffect.Effect == EffectType.OfferFunded && offerEffect.Type == OfferEffectType.Bought;
                        var cancelled        = offerEffect.Effect == EffectType.OfferCancelled && offerEffect.Type == OfferEffectType.Buy;
                        var bought           = offerEffect.Effect == EffectType.OfferBought && offerEffect.Type == OfferEffectType.Bought;
                        var partially_funded = offerEffect.Effect == EffectType.OfferPartiallyFunded && offerEffect.Type == OfferEffectType.Bought;
                        var offerFunded      = created || funded || cancelled || bought || partially_funded;
                        offerEffect.Price = GetPrice(offerEffect.GotOrPays, offerEffect.PaidOrGets, offerFunded);
                    }

                    nodeEffect = offerEffect;
                }
                else if (node.LedgerEntryType == "AccountRoot")
                {
                    if (result.Type == TxResultType.OfferEffect)
                    {
                        if (fieldsSet.RegularKey == account)
                        {
                            var regularKeyEffect = new SetRegularKeyEffect();
                            nodeEffect = regularKeyEffect;

                            regularKeyEffect.Type       = "null";
                            regularKeyEffect.Account    = fieldsSet.Account;
                            regularKeyEffect.RegularKey = account;
                        }
                    }
                }

                if (nodeEffect != null)
                {
                    effects.Add(nodeEffect);

                    if (diffType == DiffType.DeletedNode && nodeEffect.Effect != EffectType.OfferBought)
                    {
                        nodeEffect.Deleted = true;
                    }
                }
            }

            return(effects.ToArray());
        }