Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions .github/workflows/nightly-pin-watch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,27 @@ jobs:
id: definitions
continue-on-error: true
run: |
# The runner starts this script with `bash -e`, and the diff exits 1 whenever it
# finds drift: errexit would end the step at the assignment below, before the
# report is echoed or recorded - the one case the step exists for.
set +e
Comment thread
coderabbitai[bot] marked this conversation as resolved.
set -uo pipefail
out=$(dotnet run --project Tools/GenerateEnums -- diff http://localhost:5005 2>&1)
status=$?
echo "$out"
# The verdict is the tool's own Summary line, not the exit code: `dotnet run` answers 1
# both for drift and for a build that never produced a diff, and reading the code alone
# would report the second as "no differences" - the reassuring answer for the one case
# that has no answer. No Summary line means the tool did not get that far.
verdict=$(printf '%s\n' "$out" | grep -E '^Summary')
if [ -n "$verdict" ]; then
summary=$(printf '%s\n' "$out" | grep -E 'node-only|mismatch|^Summary')
else
summary=$(printf 'the definitions diff did not run (exit %s), so this section says nothing about drift; the step log above has the output' "$status")
fi
{
echo 'summary<<EOF'
printf '%s\n' "$out" | grep -E 'node-only|mismatch|^Summary' || echo 'no differences reported'
printf '%s\n' "$summary"
echo 'EOF'
echo "status=$status"
} >> "$GITHUB_OUTPUT"
Expand All @@ -212,6 +226,13 @@ jobs:
NEW_REF: ${{ steps.check.outputs.new_ref }}
AGE_DAYS: ${{ steps.check.outputs.age_days }}
BRANCH: ${{ steps.decide.outputs.branch }}
# Through the environment rather than a ${{ }} in the script below: an expression is
# pasted into the shell source before bash sees it, so a quote in the value ends the
# string and a $(...) in it runs. AMENDMENTS_* hold generated names and DEFINITIONS_SUMMARY
# carries field names the node chose, which is not text this file gets to vouch for.
AMENDMENTS_ADDED: ${{ steps.bump.outputs.added }}
AMENDMENTS_REMOVED: ${{ steps.bump.outputs.removed }}
DEFINITIONS_SUMMARY: ${{ steps.definitions.outputs.summary }}
run: |
set -euo pipefail
git config user.name "${{ github.actor }}"
Expand All @@ -227,10 +248,10 @@ jobs:
printf -- '- `.ci-config/Dockerfile.nightly`: `%s` -> `%s`\n' "$OLD_VERSION" "$NEW_VERSION"
printf -- '- `.ci-config/rippled.batchv11.cfg`: `[features]`/`[amendments]` regenerated from develop `%s`, the commit that build was made from\n\n' "$NEW_REF"
printf '## Amendment changes\n\n'
printf 'Added:\n```\n%s\n```\n\n' "${{ steps.bump.outputs.added }}"
printf 'Removed:\n```\n%s\n```\n\n' "${{ steps.bump.outputs.removed }}"
printf 'Added:\n```\n%s\n```\n\n' "$AMENDMENTS_ADDED"
printf 'Removed:\n```\n%s\n```\n\n' "$AMENDMENTS_REMOVED"
printf '## definitions.json vs the new build\n\n'
printf '```\n%s\n```\n\n' "${{ steps.definitions.outputs.summary }}"
printf '```\n%s\n```\n\n' "$DEFINITIONS_SUMMARY"
printf 'A `node-only` field here means the SDK is behind develop and needs a follow-up; `local-only` entries are informational.\n\n'
printf '## Verification\n\n'
printf 'The stand was built and started from the new pin on the runner, and the AMM sentinel amendment came up enabled at genesis, so the regenerated config was accepted.\n\n'
Expand Down
6 changes: 6 additions & 0 deletions Base/Xrpl.BinaryCodec/Enums/Field.Uint32.Generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,11 @@ public partial class Field
public static readonly Uint32Field SponsoringAccountCount = new Uint32Field(nameof(SponsoringAccountCount), 72);
public static readonly Uint32Field RemainingOwnerCount = new Uint32Field(nameof(RemainingOwnerCount), 73);
public static readonly Uint32Field SponsorFlags = new Uint32Field(nameof(SponsorFlags), 74);
public static readonly Uint32Field SubscriptionDate = new Uint32Field(nameof(SubscriptionDate), 75);
public static readonly Uint32Field RedemptionDate = new Uint32Field(nameof(RedemptionDate), 76);
public static readonly Uint32Field IssuerKeyEpoch = new Uint32Field(nameof(IssuerKeyEpoch), 77);
public static readonly Uint32Field AuditorKeyEpoch = new Uint32Field(nameof(AuditorKeyEpoch), 78);
public static readonly Uint32Field IssuerKeyMirrorEpoch = new Uint32Field(nameof(IssuerKeyMirrorEpoch), 79);
public static readonly Uint32Field AuditorKeyMirrorEpoch = new Uint32Field(nameof(AuditorKeyMirrorEpoch), 80);
}
}
2 changes: 2 additions & 0 deletions Base/Xrpl.BinaryCodec/Enums/Field.Uint8.Generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@ public partial class Field
public static readonly Uint8Field HookResult = new Uint8Field(nameof(HookResult), 18);
public static readonly Uint8Field WasLockingChainSend = new Uint8Field(nameof(WasLockingChainSend), 19);
public static readonly Uint8Field WithdrawalPolicy = new Uint8Field(nameof(WithdrawalPolicy), 20);
public static readonly Uint8Field ContractResult = new Uint8Field(nameof(ContractResult), 21);
public static readonly Uint8Field VaultKind = new Uint8Field(nameof(VaultKind), 22);
}
}
80 changes: 80 additions & 0 deletions Base/Xrpl.BinaryCodec/Enums/definitions.json
Original file line number Diff line number Diff line change
Expand Up @@ -3220,6 +3220,26 @@
"type": "UInt8"
}
],
[
"ContractResult",
{
"isSerialized": true,
"isSigningField": true,
"isVLEncoded": false,
"nth": 21,
"type": "UInt8"
}
],
[
"VaultKind",
{
"isSerialized": true,
"isSigningField": true,
"isVLEncoded": false,
"nth": 22,
"type": "UInt8"
}
],
[
"TakerPaysCurrency",
{
Expand Down Expand Up @@ -3690,6 +3710,66 @@
"type": "UInt32"
}
],
[
"SubscriptionDate",
{
"isSerialized": true,
"isSigningField": true,
"isVLEncoded": false,
"nth": 75,
"type": "UInt32"
}
],
[
"RedemptionDate",
{
"isSerialized": true,
"isSigningField": true,
"isVLEncoded": false,
"nth": 76,
"type": "UInt32"
}
],
[
"IssuerKeyEpoch",
{
"isSerialized": true,
"isSigningField": true,
"isVLEncoded": false,
"nth": 77,
"type": "UInt32"
}
],
[
"AuditorKeyEpoch",
{
"isSerialized": true,
"isSigningField": true,
"isVLEncoded": false,
"nth": 78,
"type": "UInt32"
}
],
[
"IssuerKeyMirrorEpoch",
{
"isSerialized": true,
"isSigningField": true,
"isVLEncoded": false,
"nth": 79,
"type": "UInt32"
}
],
[
"AuditorKeyMirrorEpoch",
{
"isSerialized": true,
"isSigningField": true,
"isVLEncoded": false,
"nth": 80,
"type": "UInt32"
}
],
[
"ConfidentialBalanceVersion",
{
Expand Down
28 changes: 28 additions & 0 deletions Base/Xrpl.BinaryCodec/Hashing/HashPrefix.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,34 @@ public enum HashPrefix : uint
/// </summary>
TransactionMultiSig = 0x534D5400u,
/// <summary>
/// CounterpartyTransactionSig: the preimage a LoanSet counterparty signs into
/// CounterpartySignature (rippled <c>HashPrefix::CounterpartyTxSign</c>).
/// </summary>
/// <remarks>
/// Before fixCleanup3_4_0 every signature on a transaction covered the same bytes, so a
/// signature could be lifted from one role and pasted into another. Since the amendment
/// each role has its own prefix, and the roles are the only thing that changed:
/// <see cref="TransactionSig"/> and <see cref="TransactionMultiSig"/> still cover an
/// ordinary TxnSignature, before and after.
/// </remarks>
CounterpartyTransactionSig = 0x43505400u,
/// <summary>
/// CounterpartyTransactionMultiSig: what a signer on the counterparty's SignerList signs,
/// for a CounterpartySignature carrying Signers rather than one signature
/// (rippled <c>HashPrefix::CounterpartyTxMultiSign</c>).
/// </summary>
CounterpartyTransactionMultiSig = 0x43504D00u,
/// <summary>
/// SponsorTransactionSig: the preimage a sponsor signs into SponsorSignature
/// (rippled <c>HashPrefix::SponsorTxSign</c>). See <see cref="CounterpartyTransactionSig"/>.
/// </summary>
SponsorTransactionSig = 0x53504E00u,
/// <summary>
/// SponsorTransactionMultiSig: what a signer on the sponsor's SignerList signs
/// (rippled <c>HashPrefix::SponsorTxMultiSign</c>).
/// </summary>
SponsorTransactionMultiSig = 0x53504D00u,
/// <summary>
/// Validation
/// </summary>
Validation = 0x56414C00u,
Expand Down
2 changes: 1 addition & 1 deletion Base/Xrpl.BinaryCodec/Xrpl.BinaryCodec.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/StaticBit-io/XrplCSharp</PackageProjectUrl>
<Title>XrplCSharp</Title>
<PackageVersion>11.0.1.0</PackageVersion>
<PackageVersion>11.5.0.0</PackageVersion>
</PropertyGroup>

<PropertyGroup>
Expand Down
44 changes: 42 additions & 2 deletions Base/Xrpl.BinaryCodec/XrplBinaryCodec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,28 @@ public static string Encode(object json)
/// <param name="json"></param>
/// <returns>string</returns>
public static string EncodeForSigning(object json)
{
return EncodeForSigning(json, HashPrefix.TransactionSig);
}

/// <summary>
/// Encode a transaction for signing under an explicit prefix, for a signature that is not
/// the transaction's own: <see cref="HashPrefix.SponsorTransactionSig"/> for
/// SponsorSignature, <see cref="HashPrefix.CounterpartyTransactionSig"/> for
/// CounterpartySignature.
/// </summary>
/// <remarks>
/// An overload rather than an optional parameter on the method above: a default value is
/// source-compatible but not binary-compatible, and an assembly built against the
/// one-argument signature would call a method that no longer exists.
/// </remarks>
/// <param name="json">The transaction.</param>
/// <param name="prefix">Prefix for the signing role.</param>
/// <returns>string</returns>
public static string EncodeForSigning(object json, HashPrefix prefix)
{
JsonNode node = ObjectToJsonNode(json);
return SerializeJson(node, HashPrefix.TransactionSig.Bytes(), null, true);
return SerializeJson(node, prefix.Bytes(), null, true);
}

/// <summary>
Expand Down Expand Up @@ -118,10 +137,31 @@ public static string EncodeForSigningClaim(object obj)
/// <param name="signingAccount"></param>
/// <returns>string</returns>
public static string EncodeForMultiSigning(object json, string signingAccount)
{
return EncodeForMultiSigning(json, signingAccount, HashPrefix.TransactionMultiSig);
}

/// <summary>
/// Encode a transaction for one multi-signature under an explicit prefix, for a signer on
/// a co-signing account's SignerList: <see cref="HashPrefix.SponsorTransactionMultiSig"/>
/// for SponsorSignature.Signers, <see cref="HashPrefix.CounterpartyTransactionMultiSig"/>
/// for CounterpartySignature.Signers.
/// </summary>
/// <remarks>
/// Since fixCleanup3_4_0 a Signer entry is no longer section-agnostic: an entry made for
/// the transaction's own Signers covers different bytes than the same entry inside a role
/// section, so the signer has to know which side it signs for. An overload for the same
/// binary-compatibility reason as <see cref="EncodeForSigning(object, HashPrefix)"/>.
/// </remarks>
/// <param name="json">The transaction.</param>
/// <param name="signingAccount">The account whose key signs this entry.</param>
/// <param name="prefix">Prefix for the signing role.</param>
/// <returns>string</returns>
public static string EncodeForMultiSigning(object json, string signingAccount, HashPrefix prefix)
{
string accountID = new AccountId(signingAccount).ToHex();
JsonNode token = ObjectToJsonNode(json);
return SerializeJson(token, HashPrefix.TransactionMultiSig.Bytes(), accountID.FromHex(), true);
return SerializeJson(token, prefix.Bytes(), accountID.FromHex(), true);
}

private static JsonNode ObjectToJsonNode(object obj, bool ignoreNull = false)
Expand Down
Loading
Loading