Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Batch Amendment #5060

Open
wants to merge 92 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
879aba5
featureBatch rough draft
dangell7 Jul 10, 2024
46fd68f
clang-format
dangell7 Jul 10, 2024
c57ace7
add atomic swap
dangell7 Jul 17, 2024
91d9909
Merge branch 'develop' into feature-batch
dangell7 Jul 17, 2024
f37377d
add batch `bsig`
dangell7 Jul 17, 2024
b3136a2
[fold] clang-format
dangell7 Jul 17, 2024
5e919eb
[fold] remove `tapRETRY`
dangell7 Jul 27, 2024
1225a61
[fold] remove comments
dangell7 Jul 27, 2024
304ff3e
[fold] fix invariant workaround
dangell7 Jul 27, 2024
aded948
[fold] fix applyTransaction workaround
dangell7 Jul 27, 2024
82d4943
[fold] remove test template
dangell7 Jul 27, 2024
eaf7893
[fold] update logging
dangell7 Jul 27, 2024
ca39807
[fold] remove log
dangell7 Jul 27, 2024
dd71073
clang-format
dangell7 Jul 27, 2024
26518a5
[fold] remove workaround
dangell7 Jul 27, 2024
3ceb05c
update atomic
dangell7 Jul 30, 2024
12324f1
refactor & OpenView `revert()`
dangell7 Jul 31, 2024
e9f045b
[fold] clang-format
dangell7 Jul 31, 2024
51ed234
Merge branch 'develop' into feature-batch
dangell7 Jul 31, 2024
676b9b6
[fold] add revert
dangell7 Jul 31, 2024
6c6180d
[fold] clang-format
dangell7 Jul 31, 2024
bd03ea3
[revert] remove rawRevert func
dangell7 Aug 1, 2024
c0e00b0
refactor with stacking views
dangell7 Aug 3, 2024
a3e15a1
clang-format
dangell7 Aug 3, 2024
14eef60
Merge branch 'develop' into feature-batch
dangell7 Aug 3, 2024
70e9931
[temp] invariant workaround
dangell7 Aug 3, 2024
c693b8f
update fields
dangell7 Aug 3, 2024
418836c
reject batch txn on submit
dangell7 Aug 3, 2024
fe09972
clang-format
dangell7 Aug 3, 2024
a72b070
add tests
dangell7 Aug 3, 2024
0a45c16
[fold] remove unused code
dangell7 Aug 5, 2024
2a0b9d4
include batch execution in tec failures
dangell7 Aug 5, 2024
3a9963a
atomic revert on non tec failures
dangell7 Aug 5, 2024
2c3c5c4
fix sequence & fee
dangell7 Aug 9, 2024
a54a570
Merge branch 'develop' into feature-batch
dangell7 Aug 9, 2024
3ab585b
clang-format
dangell7 Aug 9, 2024
26ee555
previousFields + nested views + signers
dangell7 Sep 5, 2024
0d5242e
clang-format
dangell7 Sep 5, 2024
51990ff
Merge branch 'develop' into feature-batch
dangell7 Sep 5, 2024
ff7fa26
add `sfBatchResult`
dangell7 Sep 5, 2024
ae5abf5
Merge branch 'develop' into feature-batch
dangell7 Sep 10, 2024
a78da6a
ticket sequence
dangell7 Sep 10, 2024
d3a2554
fix metadata
dangell7 Sep 10, 2024
e099e03
fix metadata
dangell7 Sep 10, 2024
84a69ef
fix metadata
dangell7 Sep 10, 2024
f9fe787
update tests
dangell7 Sep 10, 2024
0deea74
clang-format
dangell7 Sep 10, 2024
9266676
remove unused variable
dangell7 Sep 10, 2024
3fff4ca
rename func/field names
dangell7 Sep 10, 2024
ecfc64b
clang-format
dangell7 Sep 10, 2024
096f4bf
[fold] remove log
dangell7 Sep 10, 2024
122368f
Merge branch 'develop' into feature-batch
dangell7 Sep 12, 2024
274660b
add sfTxIDs and update signing
dangell7 Sep 18, 2024
04c5bde
clang-format
dangell7 Sep 18, 2024
e4a5c52
Merge branch 'develop' into feature-batch
dangell7 Sep 18, 2024
659e705
[fixup] rerun actions
dangell7 Sep 18, 2024
597e7fe
[fixup] remove comments
dangell7 Sep 18, 2024
639f8b7
fix no account
dangell7 Sep 22, 2024
75fd76b
clang-format
dangell7 Sep 22, 2024
2925a5d
Merge branch 'develop' into feature-batch
dangell7 Sep 24, 2024
1367e03
Merge branch 'develop' into feature-batch
dangell7 Oct 1, 2024
f185d38
[fold] remove comment
dangell7 Oct 30, 2024
767a88e
[fold] update headers
dangell7 Oct 30, 2024
ee03811
[fold] change error response text
dangell7 Oct 30, 2024
9d8368d
[fold] change flags bit
dangell7 Oct 30, 2024
b408b80
[fold] fix formatting
dangell7 Oct 30, 2024
27d4685
[fold] normal consequences
dangell7 Oct 30, 2024
419b14d
[fold] refactor single/multi sign
dangell7 Oct 30, 2024
6c87e70
[fold] review comments
dangell7 Oct 31, 2024
a75cf0e
[fold] clang-format
dangell7 Oct 31, 2024
e6021bf
[fold] tickets are not chronological
dangell7 Oct 31, 2024
fd0acb7
[fold] fix fee calculation
dangell7 Oct 31, 2024
8a6d6ce
Merge branch 'develop' into feature-batch
dangell7 Oct 31, 2024
dd77e03
[fold] fix merge issues
dangell7 Oct 31, 2024
6cb23e3
[fold] clang-format
dangell7 Oct 31, 2024
88c40e4
[fold] addressing review
dangell7 Nov 6, 2024
e4cb784
[fold] change sequence handling
dangell7 Nov 7, 2024
47120ac
[fixup] rename `prevFields` -> `batchPrevAcctRootFields`
dangell7 Nov 7, 2024
6ed4ac8
[fold] revert applyFlags change
dangell7 Nov 7, 2024
52f1ba9
[fold] use `unordered_set`
dangell7 Nov 7, 2024
1978fd3
Merge branch 'develop' into feature-batch
dangell7 Nov 7, 2024
6ffe349
[fold] clang-format
dangell7 Nov 7, 2024
04519e6
[fold] fix bad merge
dangell7 Nov 7, 2024
8029c30
[fold] address review
dangell7 Nov 11, 2024
7e60777
[fold] add quorum and out of order test
dangell7 Nov 18, 2024
403599b
[fold] add view change test
dangell7 Nov 18, 2024
d18e9b3
[fold] update to spec (BatchExecution)
dangell7 Nov 18, 2024
afe58ab
[fold] add test
dangell7 Nov 18, 2024
aec8268
[fold] add comments for Transactor.reset()
dangell7 Nov 18, 2024
086e6b0
[fold] add/update tests
dangell7 Nov 18, 2024
2ea9fe6
[fold] add tests
dangell7 Nov 18, 2024
776aabc
[fold] apply open view on open and closed
dangell7 Nov 26, 2024
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
3 changes: 2 additions & 1 deletion include/xrpl/protocol/Feature.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ namespace detail {
// Feature.cpp. Because it's only used to reserve storage, and determine how
// large to make the FeatureBitset, it MAY be larger. It MUST NOT be less than
// the actual number of amendments. A LogicError on startup will verify this.
static constexpr std::size_t numFeatures = 78;
static constexpr std::size_t numFeatures = 79;

/** Amendments that this server supports and the default voting behavior.
Whether they are enabled depends on the Rules defined in the validated
Expand Down Expand Up @@ -371,6 +371,7 @@ extern uint256 const fixReducedOffersV2;
extern uint256 const fixEnforceNFTokenTrustline;
extern uint256 const fixInnerObjTemplate2;
extern uint256 const featureInvariantsV1_1;
extern uint256 const featureBatch;

} // namespace ripple

Expand Down
9 changes: 9 additions & 0 deletions include/xrpl/protocol/SField.h
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ extern SF_UINT8 const sfScale;
extern SF_UINT8 const sfTickSize;
extern SF_UINT8 const sfUNLModifyDisabling;
extern SF_UINT8 const sfHookResult;
extern SF_UINT8 const sfBatchIndex;

// 16-bit integers (common)
extern SF_UINT16 const sfLedgerEntryType;
Expand Down Expand Up @@ -441,6 +442,7 @@ extern SF_UINT32 const sfEmitGeneration;
extern SF_UINT32 const sfVoteWeight;
extern SF_UINT32 const sfFirstNFTokenSequence;
extern SF_UINT32 const sfOracleDocumentID;
extern SF_UINT32 const sfOuterSequence;

// 64-bit integers (common)
extern SF_UINT64 const sfIndexNext;
Expand Down Expand Up @@ -650,6 +652,10 @@ extern SField const sfXChainClaimProofSig;
extern SField const sfXChainCreateAccountProofSig;
extern SField const sfXChainClaimAttestationCollectionElement;
extern SField const sfXChainCreateAccountAttestationCollectionElement;
extern SField const sfRawTransaction;
extern SField const sfBatchExecution;
extern SField const sfBatchTxn;
extern SField const sfBatchSigner;

// array of objects (common)
// ARRAY/1 is reserved for end of array
Expand All @@ -675,6 +681,9 @@ extern SField const sfHookParameters;
extern SField const sfHookGrants;
extern SField const sfXChainClaimAttestations;
extern SField const sfXChainCreateAccountAttestations;
extern SField const sfBatchExecutions;
extern SField const sfRawTransactions;
extern SField const sfBatchSigners;

//------------------------------------------------------------------------------

Expand Down
3 changes: 3 additions & 0 deletions include/xrpl/protocol/STTx.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ class STTx final : public STObject, public CountedObject<STTx>
checkSign(RequireFullyCanonicalSig requireCanonicalSig, Rules const& rules)
const;

Expected<void, std::string>
checkBatchSign() const;

// SQL Functions with metadata.
static std::string const&
getMetaSQLInsertReplaceHeader();
Expand Down
3 changes: 2 additions & 1 deletion include/xrpl/protocol/TER.h
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,8 @@ enum TECcodes : TERUnderlyingType {
tecINVALID_UPDATE_TIME = 188,
tecTOKEN_PAIR_NOT_FOUND = 189,
tecARRAY_EMPTY = 190,
tecARRAY_TOO_LARGE = 191
tecARRAY_TOO_LARGE = 191,
tecBATCH_FAILURE = 192
};

//------------------------------------------------------------------------------
Expand Down
8 changes: 8 additions & 0 deletions include/xrpl/protocol/TxFlags.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,14 @@ constexpr std::uint32_t tfDepositMask = ~(tfUniversal | tfDepositSubTx);
constexpr std::uint32_t tfClearAccountCreateAmount = 0x00010000;
constexpr std::uint32_t tfBridgeModifyMask = ~(tfUniversal | tfClearAccountCreateAmount);

// Batch Flags
dangell7 marked this conversation as resolved.
Show resolved Hide resolved
constexpr std::uint32_t tfAllOrNothing = 0x00000001;
constexpr std::uint32_t tfOnlyOne = 0x00000002;
constexpr std::uint32_t tfUntilFailure = 0x00000004;
constexpr std::uint32_t tfIndependent = 0x00000008;
dangell7 marked this conversation as resolved.
Show resolved Hide resolved
dangell7 marked this conversation as resolved.
Show resolved Hide resolved
constexpr std::uint32_t const tfBatchMask =
~(tfUniversal | tfAllOrNothing | tfOnlyOne | tfUntilFailure | tfIndependent);

// clang-format on

} // namespace ripple
Expand Down
3 changes: 3 additions & 0 deletions include/xrpl/protocol/TxFormats.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ enum TxType : std::uint16_t
/** This transaction type deletes an Oracle instance */
ttORACLE_DELETE = 52,

/** This transaction type creates a Batch instance */
ttBATCH = 53,

/** This system-generated transaction type is used to update the status of the various amendments.

For details, see: https://xrpl.org/amendments.html
Expand Down
18 changes: 18 additions & 0 deletions include/xrpl/protocol/TxMeta.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,31 @@ class TxMeta
return static_cast<bool>(mDelivered);
}

STArray const&
getBatchExecutions() const
{
return *mBatchExecutions;
}

void
setBatchExecutions(STArray const& batchExecutions)
{
mBatchExecutions = batchExecutions;
}
bool
dangell7 marked this conversation as resolved.
Show resolved Hide resolved
hasBatchExecutions() const
{
return static_cast<bool>(mBatchExecutions);
}

private:
uint256 mTransactionID;
std::uint32_t mLedger;
std::uint32_t mIndex;
int mResult;

std::optional<STAmount> mDelivered;
std::optional<STArray> mBatchExecutions;

STArray mNodes;
};
Expand Down
2 changes: 2 additions & 0 deletions include/xrpl/protocol/jss.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ JSS(AssetPrice); // in: Oracle
JSS(AuthAccount); // in: AMM Auction Slot
JSS(AuthAccounts); // in: AMM Auction Slot
JSS(BaseAsset); // in: Oracle
JSS(Batch); // transaction type
JSS(Bridge); // ledger type.
JSS(Check); // ledger type.
JSS(CheckCancel); // transaction type.
Expand Down Expand Up @@ -128,6 +129,7 @@ JSS(PriceData); // field.
JSS(Provider); // field.
JSS(QuoteAsset); // in: Oracle.
JSS(RippleState); // ledger type.
JSS(RawTransaction); // in: Batch
JSS(SLE_hit_rate); // out: GetCounts.
JSS(SetFee); // transaction type.
JSS(UNLModify); // transaction type.
Expand Down
1 change: 1 addition & 0 deletions src/libxrpl/protocol/Feature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ REGISTER_FIX (fixInnerObjTemplate2, Supported::yes, VoteBehavior::De
// InvariantsV1_1 will be changes to Supported::yes when all the
// invariants expected to be included under it are complete.
REGISTER_FEATURE(InvariantsV1_1, Supported::no, VoteBehavior::DefaultNo);
REGISTER_FEATURE(Batch, Supported::yes, VoteBehavior::DefaultNo);

// The following amendments are obsolete, but must remain supported
// because they could potentially get enabled.
Expand Down
19 changes: 19 additions & 0 deletions src/libxrpl/protocol/InnerObjectFormats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,25 @@ InnerObjectFormats::InnerObjectFormats()
{sfAssetPrice, soeOPTIONAL},
{sfScale, soeDEFAULT},
});

add(sfBatchExecution.jsonName.c_str(),
sfBatchExecution.getCode(),
{{sfTransactionType, soeREQUIRED},
{sfTransactionResult, soeREQUIRED},
{sfTransactionHash, soeOPTIONAL}});

add(sfBatchTxn.jsonName.c_str(),
sfBatchTxn.getCode(),
{{sfAccount, soeREQUIRED},
{sfOuterSequence, soeREQUIRED},
{sfSequence, soeOPTIONAL},
{sfBatchIndex, soeREQUIRED}});
dangell7 marked this conversation as resolved.
Show resolved Hide resolved

add(sfBatchSigner.jsonName.c_str(),
sfBatchSigner.getCode(),
{{sfAccount, soeREQUIRED},
{sfSigningPubKey, soeREQUIRED},
{sfTxnSignature, soeREQUIRED}});
}

InnerObjectFormats const&
Expand Down
9 changes: 9 additions & 0 deletions src/libxrpl/protocol/SField.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ CONSTRUCT_TYPED_SFIELD(sfTickSize, "TickSize", UINT8,
CONSTRUCT_TYPED_SFIELD(sfUNLModifyDisabling, "UNLModifyDisabling", UINT8, 17);
CONSTRUCT_TYPED_SFIELD(sfHookResult, "HookResult", UINT8, 18);
CONSTRUCT_TYPED_SFIELD(sfWasLockingChainSend, "WasLockingChainSend", UINT8, 19);
CONSTRUCT_TYPED_SFIELD(sfBatchIndex, "BatchIndex", UINT8, 20);

// 16-bit integers
CONSTRUCT_TYPED_SFIELD(sfLedgerEntryType, "LedgerEntryType", UINT16, 1, SField::sMD_Never);
Expand Down Expand Up @@ -167,6 +168,7 @@ CONSTRUCT_TYPED_SFIELD(sfEmitGeneration, "EmitGeneration", UINT32,
CONSTRUCT_TYPED_SFIELD(sfVoteWeight, "VoteWeight", UINT32, 48);
CONSTRUCT_TYPED_SFIELD(sfFirstNFTokenSequence, "FirstNFTokenSequence", UINT32, 50);
CONSTRUCT_TYPED_SFIELD(sfOracleDocumentID, "OracleDocumentID", UINT32, 51);
CONSTRUCT_TYPED_SFIELD(sfOuterSequence, "OuterSequence", UINT32, 52);

// 64-bit integers (common)
CONSTRUCT_TYPED_SFIELD(sfIndexNext, "IndexNext", UINT64, 1);
Expand Down Expand Up @@ -390,6 +392,10 @@ CONSTRUCT_UNTYPED_SFIELD(sfXChainCreateAccountAttestationCollectionElement,
"XChainCreateAccountAttestationCollectionElement",
OBJECT, 31);
CONSTRUCT_UNTYPED_SFIELD(sfPriceData, "PriceData", OBJECT, 32);
CONSTRUCT_UNTYPED_SFIELD(sfRawTransaction, "RawTransaction", OBJECT, 33);
CONSTRUCT_UNTYPED_SFIELD(sfBatchExecution, "BatchExecution", OBJECT, 34);
CONSTRUCT_UNTYPED_SFIELD(sfBatchTxn, "BatchTxn", OBJECT, 35);
CONSTRUCT_UNTYPED_SFIELD(sfBatchSigner, "BatchSigner", OBJECT, 36);

// array of objects
// ARRAY/1 is reserved for end of array
Expand Down Expand Up @@ -420,6 +426,9 @@ CONSTRUCT_UNTYPED_SFIELD(sfXChainCreateAccountAttestations,
// 23 is unused and available for use
CONSTRUCT_UNTYPED_SFIELD(sfPriceDataSeries, "PriceDataSeries", ARRAY, 24);
CONSTRUCT_UNTYPED_SFIELD(sfAuthAccounts, "AuthAccounts", ARRAY, 25);
CONSTRUCT_UNTYPED_SFIELD(sfBatchExecutions, "BatchExecutions", ARRAY, 26);
CONSTRUCT_UNTYPED_SFIELD(sfRawTransactions, "RawTransactions", ARRAY, 27);
CONSTRUCT_UNTYPED_SFIELD(sfBatchSigners, "BatchSigners", ARRAY, 28, SField::sMD_Default, SField::notSigning);

// clang-format on

Expand Down
87 changes: 87 additions & 0 deletions src/libxrpl/protocol/STTx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,17 @@ STTx::getSeqProxy() const
if (seq != 0)
return SeqProxy::sequence(seq);

if (isFieldPresent(sfBatchTxn))
{
STObject const batchTxn = const_cast<ripple::STTx&>(*this)
dangell7 marked this conversation as resolved.
Show resolved Hide resolved
.getField(sfBatchTxn)
.downcast<STObject>();
std::uint32_t const startSequence{
dangell7 marked this conversation as resolved.
Show resolved Hide resolved
batchTxn.getFieldU32(sfOuterSequence)};
std::uint32_t const batchIndex{batchTxn.getFieldU8(sfBatchIndex)};
return SeqProxy::sequence(startSequence + batchIndex);
dangell7 marked this conversation as resolved.
Show resolved Hide resolved
}

std::optional<std::uint32_t> const ticketSeq{operator[](~sfTicketSequence)};
if (!ticketSeq)
// No TicketSequence specified. Return the Sequence, whatever it is.
Expand Down Expand Up @@ -346,6 +357,82 @@ STTx::checkSingleSign(RequireFullyCanonicalSig requireCanonicalSig) const
return {};
}

Expected<void, std::string>
STTx::checkBatchSign() const
{
STArray const& signers{getFieldArray(sfBatchSigners)};

// There are well known bounds that the number of signers must be within.
if (signers.size() == 0 || signers.size() > 8)
return Unexpected("Invalid Batch Signers array size.");

// We can ease the computational load inside the loop a bit by
// pre-constructing part of the data that we hash. Fill a Serializer
// with the stuff that stays constant from signature to signature.

Serializer const dataStart{startMultiSigningData(*this)};

// We also use the sfAccount field inside the loop. Get it once.
// auto const txnAccountID = getAccountID(sfAccount);

// Determine whether signatures must be full canonical.
bool const fullyCanonical = true;

// Signers must be in sorted order by AccountID.
AccountID lastAccountID(beast::zero);

for (auto const& signer : signers)
{
auto const accountID = signer.getAccountID(sfAccount);

// // The account owner may not multisign for themselves.
// if (accountID == txnAccountID)
// return Unexpected("Invalid multisigner.");

// No duplicate signers allowed.
if (lastAccountID == accountID)
return Unexpected("Duplicate Signers not allowed.");

// Accounts must be in order by account ID. No duplicates allowed.
if (lastAccountID > accountID)
return Unexpected("Unsorted Signers array.");

// The next signature must be greater than this one.
lastAccountID = accountID;

// Verify the signature.
bool validSig = false;
try
{
Serializer s = dataStart;
finishMultiSigningData(accountID, s);

auto spk = signer.getFieldVL(sfSigningPubKey);

if (publicKeyType(makeSlice(spk)))
{
Blob const signature = signer.getFieldVL(sfTxnSignature);
validSig = verify(
PublicKey(makeSlice(spk)),
s.slice(),
makeSlice(signature),
fullyCanonical);
}
}
catch (std::exception const&)
{
// We assume any problem lies with the signature.
validSig = false;
}
if (!validSig)
return Unexpected(
std::string("Invalid signature on account ") +
toBase58(accountID) + ".");
}
// All signatures verified.
return {};
}

Expected<void, std::string>
STTx::checkMultiSign(
RequireFullyCanonicalSig requireCanonicalSig,
Expand Down
1 change: 1 addition & 0 deletions src/libxrpl/protocol/TER.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ transResults()
MAKE_ERROR(tecTOKEN_PAIR_NOT_FOUND, "Token pair is not found in Oracle object."),
MAKE_ERROR(tecARRAY_EMPTY, "Array is empty."),
MAKE_ERROR(tecARRAY_TOO_LARGE, "Array is too large."),
MAKE_ERROR(tecBATCH_FAILURE, "Tx Batch Failure."),
dangell7 marked this conversation as resolved.
Show resolved Hide resolved

MAKE_ERROR(tefALREADY, "The exact transaction was already in this ledger."),
MAKE_ERROR(tefBAD_ADD_AUTH, "Not authorized to add account."),
Expand Down
9 changes: 9 additions & 0 deletions src/libxrpl/protocol/TxFormats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ TxFormats::TxFormats()
{sfTxnSignature, soeOPTIONAL},
{sfSigners, soeOPTIONAL}, // submit_multisigned
{sfNetworkID, soeOPTIONAL},
{sfBatchTxn, soeOPTIONAL},
};

add(jss::AccountSet,
Expand Down Expand Up @@ -505,6 +506,14 @@ TxFormats::TxFormats()
{sfOracleDocumentID, soeREQUIRED},
},
commonFields);

add(jss::Batch,
ttBATCH,
{
{sfRawTransactions, soeREQUIRED},
{sfBatchSigners, soeOPTIONAL},
},
commonFields);
}

TxFormats const&
Expand Down
8 changes: 8 additions & 0 deletions src/libxrpl/protocol/TxMeta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ TxMeta::TxMeta(

if (obj.isFieldPresent(sfDeliveredAmount))
setDeliveredAmount(obj.getFieldAmount(sfDeliveredAmount));

if (obj.isFieldPresent(sfBatchExecutions))
setBatchExecutions(obj.getFieldArray(sfBatchExecutions));
}

TxMeta::TxMeta(uint256 const& txid, std::uint32_t ledger, STObject const& obj)
Expand All @@ -61,6 +64,9 @@ TxMeta::TxMeta(uint256 const& txid, std::uint32_t ledger, STObject const& obj)

if (obj.isFieldPresent(sfDeliveredAmount))
setDeliveredAmount(obj.getFieldAmount(sfDeliveredAmount));

if (obj.isFieldPresent(sfBatchExecutions))
setBatchExecutions(obj.getFieldArray(sfBatchExecutions));
}

TxMeta::TxMeta(uint256 const& txid, std::uint32_t ledger, Blob const& vec)
Expand Down Expand Up @@ -205,6 +211,8 @@ TxMeta::getAsObject() const
metaData.emplace_back(mNodes);
if (hasDeliveredAmount())
metaData.setFieldAmount(sfDeliveredAmount, getDeliveredAmount());
if (hasBatchExecutions())
metaData.setFieldArray(sfBatchExecutions, getBatchExecutions());
return metaData;
}

Expand Down
Loading
Loading