public AccountId CreatedAccount() { AccountId destination = null; Hash256 destinationIndex = null; if (TransactionType == TransactionType.Payment && Meta.Has(Field.AffectedNodes)) { StArray affected = Meta[StArray.AffectedNodes]; foreach (var node in affected) { if (node.Has(StObject.CreatedNode)) { StObject created = node[StObject.CreatedNode]; if (StObject.LedgerEntryType(created) == LedgerEntryType.AccountRoot) { if (destination == null) { destination = Txn[AccountId.Destination]; destinationIndex = Hash256.AccountIdLedgerIndex(destination); } if (destinationIndex.Equals(created[Hash256.LedgerHash])) { return(destination); } } } } } return(null); }
public void testParsingVector256() { // This was a test case for a bug found in ripple-lib js string jsonHexed = "110064220000000058000360186E008422E06B72D5B275E29EE3BE9D87A370F424E0E7BF613C4659098214289D19799C892637306AAAF03805EDFCDF6C28B8011320081342A0AB45459A54D8E4FA1842339A102680216CF9A152BCE4F4CE467D8246"; StObject meta = StObject.OutTranslate.FromHex(jsonHexed); string expectedJSON; expectedJSON = "{\"LedgerEntryType\":\"DirectoryNode\",\"Indexes\":[\"081342A0AB45459A54D8E4FA1842339A102680216CF9A152BCE4F4CE467D8246\"],\"Owner\":\"rh6kN9s7spSb3vdv6H8ZGYzsddSLeEUGmc\",\"RootIndex\":\"000360186E008422E06B72D5B275E29EE3BE9D87A370F424E0E7BF613C465909\",\"Flags\":0}"; var parsedJson = JObject.Parse(expectedJSON); var jObj = meta.ToJObject(); foreach (var keyPair in parsedJson) { JToken val; if (jObj.TryGetValue(keyPair.Key, out val)) { Assert.AreEqual(keyPair.Value, val); } } //Assert.AreEqual(expectedJSON, meta.ToJObject().ToString(Formatting.None)); }
public SignedTx SignStObject(StObject tx) { tx.SetFlag(CanonicalSigFlag); tx[Field.SigningPubKey] = _keyPair.CanonicalPubBytes(); tx[Field.TxnSignature] = _keyPair.Sign(tx.SigningData()); return(ValidateAndEncode(tx)); }
/** * We just testing this won't blow up due to unknown `date` field! */public void testFromJObjectWithUnknownFields() { string json = "{\"date\": 434707820,\n" + "\"hash\": \"66347806574036FD3D3E9FDA20A411FA8B2D26AA3C3725A107FCF0050F1E4B86\"}"; StObject so = StObject.FromJObject(JObject.Parse(json)); }
public void testTreeMapSuitability() { Hash256 a = new Hash256(new byte[32]); Hash256 b = new Hash256(new byte[32]); Hash256 c = new Hash256(new byte[32]); Hash256 d = new Hash256(new byte[32]); StObject objectA = new StObject(); StObject objectB = new StObject(); StObject objectC = new StObject(); a.Bytes[0] = (byte)'a'; b.Bytes[0] = (byte)'b'; c.Bytes[0] = (byte)'c'; d.Bytes[0] = (byte)'a'; var tree = new Hash256.Hash256Map <StObject> { { a, objectA } }; // There can be ONLY one Assert.True(tree.ContainsKey(d)); tree.Add(b, objectB); tree.Add(c, objectC); Assert.True(tree[a] == objectA); Assert.True(tree[b] == objectB); Assert.True(tree[c] == objectC); }
public void CanDecodeMetaBinary() { var meta = "201C00000000F8E511006125004D1B5655AB8953C6EFD2EBDD5D6314CE0DAFF4CA5B180AE1792B47468ECA5EC5AED28CA45698430F87624433A745D429635D1B2B982EF22AC7E4112ACF43DA97AEF258DC76E6624000000254C5E530E1E7220000000024000000022D00000000624000000254D527708114A2D0815DD52160FF1979A60C50B00C09ECD669D4E1E1E511006125004D1B5655AB8953C6EFD2EBDD5D6314CE0DAFF4CA5B180AE1792B47468ECA5EC5AED28CA456CECECAD86B8E831AA8DB7C8AE259D7D5C1B85C6A5FB9A4341CF560DFB8242F10E624000000126240000002534F23B0E1E7220000000024000000132D000000016240000002533FE1668114656CFDA8B366CAFE7EDC195A6DE87921FB70C231E1E1F1031000"; StObject obj = StObject.FromHex(meta); Assert.IsNotNull(obj); }
public void CanDeserializeEscrowTransaction() { string binary = "1200012280000000240000001C201B0055E830202421E4C840202521E376C061400000000098968068400000000000000C7321024B1C46885AD9DEEE7A413026D74BA6161C2F68FA9BD621022CF34CA00FB6FAEC7446304402201E931F36789387DF59058D34345D5EEBF2BD18159FEB8A8601E495054D4065F802200EBD2738EA138BA7C0D5AC07E02B950A84F563EF1AC94F8B4BCAA99595B402A48114656CFDA8B366CAFE7EDC195A6DE87921FB70C2318314A2D0815DD52160FF1979A60C50B00C09ECD669D4"; StObject stObject = StObject.FromHex(binary); Assert.IsNotNull(stObject); }
private static SignedTx GetSignedTx(StObject tx, TestAccount src) { if (tx.Has(Field.Signers) || tx.Has(Field.TxnSignature)) { return(TxSigner.ValidateAndEncode(tx)); } return(src.Signer.SignStObject(tx)); }
public void CanDecodeBinary() { string binary = "1100722200210000250178D1CA37000000000000000038000000000000028355C0C37CE200B509E0A529880634F7841A9EF4CB65F03C12E6004CFAD9718D66946280000000000000000000000000000000000000004743420000000000000000000000000000000000000000000000000166D6071AFD498D000000000000000000000000000047434200000000002599D1D255BCA61189CA64C84528F2FCBE4BFC3867800000000000000000000000000000000000000047434200000000006EEBB1D1852CE667876A0B3630861FB6C6AB358E"; var obj = StObject.FromHex(binary); Assert.IsNotNull(obj); }
public void MissingFieldsTest() { var so = new StObject { [Field.TransactionType] = TransactionType.Payment }; TxFormat.Validate(so); }
public TxResult(StObject tx, StObject meta, Uint32 ledgerIndex) { Tx = tx; Meta = meta; LedgerIndex = ledgerIndex; Hash = tx[Field.hash]; Result = meta[Field.TransactionResult]; TxIndex = meta[Field.TransactionIndex]; Type = tx[Field.TransactionType]; }
public static void Validate(StObject obj) { var errors = new List \ \ (); Validate(obj, errors.Add); if (errors.Count \ > \ 0) { throw new TxFormatValidationException(string.Join("\n", errors)); } }
public void testParsing() { string jsonHexed = "201C00000001F8E511006125003136FA55610A3178D0A69167DF32E28990FD60D50F5610A5CF5C832CBF0C7FCC0913516B5656091AD066271ED03B106812AD376D48F126803665E3ECBFDBBB7A3FFEB474B2E62400113FCF2D000000456240000000768913E4E1E722000000002400113FD02D000000446240000000768913DA8114E0E893E991B2142E74486F7D3331CF711EA84213E1E1E5110064565943CB2C05B28743AADF0AE47E9C57E9C15BD23284CF6DA9561993D688DA919AE7220000000036561993D688DA919A585943CB2C05B28743AADF0AE47E9C57E9C15BD23284CF6DA9561993D688DA919A01110000000000000000000000004C54430000000000021192D705968936C419CE614BF264B5EEB1CEA47FF403110000000000000000000000004254430000000000041192D705968936C419CE614BF264B5EEB1CEA47FF4E1E1E411006F5678812E6E2AB80D5F291F8033D7BC23F0A6E4EA80C998BFF38E80E2A09D2C4D93E722000000002400113F32250031361633000000000000000034000000000000329255C7D1671589B1B4AB1071E38299B8338632DAD19A7D0F8D28388F40845AF0BCC550105943CB2C05B28743AADF0AE47E9C57E9C15BD23284CF6DA9561993D688DA919A64D4C7A75562493C000000000000000000000000004C5443000000000092D705968936C419CE614BF264B5EEB1CEA47FF465D44AA183A77ECF80000000000000000000000000425443000000000092D705968936C419CE614BF264B5EEB1CEA47FF48114E0E893E991B2142E74486F7D3331CF711EA84213E1E1E511006456F78A0FFA69890F27C2A79C495E1CEB187EE8E677E3FDFA5AD0B8FCFC6E644E38E72200000000310000000000003293320000000000000000582114A41BB356843CE99B2858892C8F1FEF634B09F09AF2EB3E8C9AA7FD0E3A1A8214E0E893E991B2142E74486F7D3331CF711EA84213E1E1F1031000"; StObject meta = StObject.OutTranslate.FromParser(new BinaryParser(jsonHexed)); string actual = meta.ToHex(); Assert.AreEqual(jsonHexed.Length, actual.Length); Assert.AreEqual(jsonHexed, actual); }
public StObject Executed(StObject finalFields) { // Where 'this' is an AffectedNode nodeAsPrevious. var executed = new StObject { { Amount.TakerPays, finalFields[Amount.TakerPays].Subtract(TakerPays).Abs() }, { Amount.TakerGets, finalFields[Amount.TakerGets].Subtract(TakerGets).Abs() } }; return(executed); }
public void testFormatted() { StObject offer = new StObject(); offer.Add(UInt16.LedgerEntryType, LedgerEntryType.Offer.AsInteger); offer.Add(Amount.TakerGets, "1.0"); offer.Add(Amount.TakerPays, "2.0"); Offer casted = (Offer)StObject.Formatted(offer); Assert.AreEqual(casted.AskQuality.ToPlainString(), "2"); }
public async Task <TxSubmission> AccountSet( TestAccount src, TxConfigurator[] configure = null) { var offer = new StObject { [Field.TransactionType] = TransactionType.AccountSet }; var signed = SignAndConfigure(src, offer, configure); return(await Ws.Submit(signed.TxBlob)); }
public void testTypeInference() { StObject so = StObject.NewInstance(); so.Add(Field.FromString("LowLimit"), "10.0/USD"); so.Add(Amount.Balance, "125.0"); Assert.AreEqual(so[Amount.Balance].ToDropsString(), "125000000"); Assert.AreEqual(so[Amount.LowLimit].CurrencyString, "USD"); Assert.NotNull(so[Amount.LowLimit]); Assert.Null(so[Amount.HighLimit]); }
/// \\ /// /// \\ /// \\\\ /// \\\\ /// \\Thrown when provided Json transaction is not valid.\\ public SignedTx SignJson(JObject tx) { StObject so; try { so = StObject.FromJson(tx, strict: true); } catch (InvalidJsonException ex) { throw new InvalidTxException("Transaction is not valid.", nameof(tx), ex); } return(SignStObject(so)); }
public void DataDrivenTransactionSerialisationTest() { var obj = GetTestsJson(); foreach (var whole in obj["whole_objects"]) { StObject txn = whole["tx_json"]; Assert.AreEqual(whole["blob_with_no_signing"], txn.ToHex()); AssertDeepEqual(whole["tx_json"], txn.ToJson(), null); var txnFromBinary = StObject.FromHex($"{whole["blob_with_no_signing"]}"); AssertDeepEqual(whole["tx_json"], txnFromBinary.ToJson(), null); } }
public static void AssertRecycles(string jsonKey, string binaryKey, JToken test) { var json = test[jsonKey]; var binary = test[binaryKey]; string expectedHex = binary.ToString(); var fromHex = StObject.FromHex(expectedHex); AssertDeepEqual(json, fromHex.ToJson(), test); StObject o = json; var actualHex = o.ToHex(); Assert.AreEqual(expectedHex, actualHex, $"{test}"); }
public StObject RebuildFromMeta(bool layerPrevious) { var mixed = new StObject(); bool created = IsCreatedNode; var wrapperField = created ? Field.CreatedNode : IsDeletedNode ? Field.DeletedNode : Field.ModifiedNode; var wrapped = (StObject) base[wrapperField]; var finalFields = created ? Field.NewFields : Field.FinalFields; var finals = (StObject)wrapped[finalFields]; foreach (var field in finals) { mixed.Add(field, finals[field]); } // DirectoryNode LedgerEntryType won't have `PreviousFields` if (layerPrevious && wrapped.Has(Field.PreviousFields)) { var previous = wrapped[PreviousFields]; var changed = new StObject(); mixed.Add(Field.FinalFields, changed); foreach (var field in previous) { mixed.Add(field, previous[field]); changed.Add(field, finals[field]); } } foreach (var field in wrapped) { if (field == Field.NewFields || field == Field.PreviousFields || field == Field.FinalFields) { continue; } mixed.Add(field, wrapped[field]); } return(Formatted(mixed)); }
public async Task <TxSubmission> OfferCancel( TestAccount src, Uint32 cancel, TxConfigurator[] configure = null) { var offer = new StObject { [Field.TransactionType] = TransactionType.OfferCreate, [Field.OfferSequence] = cancel }; var signed = SignAndConfigure(src, offer, configure); return(await Ws.Submit(signed.TxBlob)); }
public async Task <TxSubmission> Trust( TestAccount src, Amount amt, TxConfigurator[] configure = null) { var trustSet = new StObject { [Field.TransactionType] = TransactionType.TrustSet, [Field.LimitAmount] = amt }; var signed = SignAndConfigure(src, trustSet, configure); return(await Ws.Submit(signed.TxBlob)); }
public void AutoPopulateFields(TestAccount src, StObject tx) { if (!tx.Has(Field.Sequence)) { tx[Field.Sequence] = src.NextSequence++; } if (!tx.Has(Field.Fee)) { tx[Field.Fee] = DefaultFee; } if (!tx.Has(Field.Account)) { tx[Field.Account] = src.Id; } }
public StObject RebuildFromMeta(bool layerPrevious) { var mixed = new StObject(); bool created = IsCreatedNode; var wrapperField = created ? Field.CreatedNode : IsDeletedNode ? Field.DeletedNode : Field.ModifiedNode; var wrapped = (StObject)base[wrapperField]; var finalFields = created ? Field.NewFields : Field.FinalFields; var finals = (StObject) wrapped[finalFields]; foreach (var field in finals) { mixed.Add(field, finals[field]); } // DirectoryNode LedgerEntryType won't have `PreviousFields` if (layerPrevious && wrapped.Has(Field.PreviousFields)) { var previous = wrapped[PreviousFields]; var changed = new StObject(); mixed.Add(Field.FinalFields, changed); foreach (var field in previous) { mixed.Add(field, previous[field]); changed.Add(field, finals[field]); } } foreach (var field in wrapped) { if (field == Field.NewFields || field == Field.PreviousFields || field == Field.FinalFields) { continue; } mixed.Add(field, wrapped[field]); } return Formatted(mixed); }
public void testSymbolics() { Assert.NotNull(TxFormat.FromString("Payment")); JObject json = JObject.Parse("{\"Expiration\" : 21, " + "\"TransactionResult\" : 0, " + "\"TransactionType\" : 0 }"); StObject so = StObject.OutTranslate.FromJObject(json); Assert.AreEqual(so.GetFormat, TxFormat.Payment); so.SetFormat(null); // Else it (SHOULD) attempt to validate something clearly unFormatted JObject obj = StObject.InTranslate.ToJObject(so); Assert.AreEqual(obj["TransactionResult"].ToString(), "tesSUCCESS"); Assert.AreEqual(obj["TransactionType"].ToString(), "Payment"); }
public void TransactionSigningTest() { var json = JObject.Parse(TxJson); var obj = StObject.FromJson(json); var hex = obj.ToHex(); // The MessageBytes includes the HashPrefix Assert.AreEqual(MessageBytes.Substring(8), hex); Seed seed = Seed.FromPassPhrase("niq").SetEd25519(); // The ed25519 Signature var sig = seed.KeyPair().Sign(B16.Decode(MessageBytes)); var expectedSig = ExpectedSig; Assert.AreEqual(expectedSig, B16.Encode(sig)); }
public async Task <TxSubmission> Offer( TestAccount src, Amount pays, Amount gets, TxConfigurator[] configure = null) { var offer = new StObject { [Field.TransactionType] = TransactionType.OfferCreate, [Field.TakerPays] = pays, [Field.TakerGets] = gets }; var signed = SignAndConfigure(src, offer, configure); return(await Ws.Submit(signed.TxBlob)); }
public static SignedTx ValidateAndEncode(StObject tx) { try { TxFormat.Validate(tx); } catch (TxFormatValidationException ex) { throw new InvalidTxException("Transaction is not valid.", nameof(tx), ex); } var blob = tx.ToBytes(); var hash = Utils.TransactionId(blob); return(new SignedTx(hash, B16.Encode(blob), tx.ToJsonObject())); }
private static ShaMap ParseAccountState(JArray state) { var stateMap = new ShaMap(); var entries = state.Select((t) => { StObject so = t["json"]; Assert.AreEqual(t["binary"].ToString(), so.ToHex(), t.ToString() + " " + so.ToJson()); return(new LedgerEntry(so)); }); foreach (var ledgerEntry in entries) { stateMap.AddItem(ledgerEntry.Index(), ledgerEntry); } return(stateMap); }
internal static void Validate(StObject obj, Action \ \ onError) { if (!obj.Has(Field.TransactionType)) { onError("Missing `TransactionType` field"); return; } var tt = obj[Field.TransactionType]; if (tt == null) { onError("`TransactionType` is set to null"); return; } var format = Formats[tt]; var allFields = new SortedSet \ \ (obj.Fields.Keys); allFields.UnionWith(format.Keys); foreach (var field in allFields) { var inFormat = format.ContainsKey(field); ISerializedType fieldValue; var inObject = obj.Fields.TryGetValue(field, out fieldValue); if (!inFormat) { onError($"`{tt}` has no `{field}` field"); } else if (format[field] == Requirement.Required) { if (!inObject) { onError($"`{tt}` has required field `{field}`"); } else if (fieldValue == null) { onError($"Required field `{field}` is set to null"); } // TODO: associated type for field is wrong // It should be nearly impossible anyway because FromJson // throws when the json is invalid for the field type and // the StObject[] indexers all use typed fields externally } } }
public AffectedNode(StObject source) { fields = source.Fields; _field = Field; _nested = GetNested; }
public static bool IsAffectedNode(StObject source) { return (source.Count == 1 && source.Has(DeletedNode) || source.Has(CreatedNode) || source.Has(ModifiedNode)); }