Fixes #769
This commit is contained in:
cyan317
2023-07-26 17:12:20 +01:00
committed by GitHub
parent 6b98579bfb
commit 71aabc8c29
9 changed files with 672 additions and 6 deletions

View File

@@ -19,12 +19,15 @@
#include "TestObject.h"
#include <backend/DBHelpers.h>
#include <rpc/RPCHelpers.h>
#include <ripple/protocol/STArray.h>
#include <ripple/protocol/TER.h>
#include <chrono>
constexpr static auto INDEX1 = "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC";
ripple::AccountID
GetAccountIDWithString(std::string_view id)
{
@@ -529,3 +532,200 @@ CreateNFTTokenPage(
tokenPage.setFieldArray(ripple::sfNFTokens, list);
return tokenPage;
}
Backend::TransactionAndMetadata
CreateMintNFTTxWithMetadata(
std::string_view accountId,
uint32_t seq,
uint32_t fee,
uint32_t nfTokenTaxon,
std::string_view nftID)
{
// tx
ripple::STObject tx(ripple::sfTransaction);
tx.setFieldU16(ripple::sfTransactionType, ripple::ttNFTOKEN_MINT);
auto account = ripple::parseBase58<ripple::AccountID>(std::string(accountId));
tx.setAccountID(ripple::sfAccount, account.value());
auto amount = ripple::STAmount(fee, false);
tx.setFieldAmount(ripple::sfFee, amount);
// required field for ttNFTOKEN_MINT
tx.setFieldU32(ripple::sfNFTokenTaxon, nfTokenTaxon);
tx.setFieldU32(ripple::sfSequence, seq);
const char* key = "test";
ripple::Slice slice(key, 4);
tx.setFieldVL(ripple::sfSigningPubKey, slice);
// meta
ripple::STObject metaObj(ripple::sfTransactionMetaData);
ripple::STArray metaArray{1};
ripple::STObject node(ripple::sfModifiedNode);
node.setFieldU16(ripple::sfLedgerEntryType, ripple::ltNFTOKEN_PAGE);
ripple::STObject finalFields(ripple::sfFinalFields);
ripple::STArray NFTArray1{2};
// finalFields contain new NFT while previousFields does not
auto entry = ripple::STObject(ripple::sfNFToken);
entry.setFieldH256(ripple::sfNFTokenID, ripple::uint256{nftID});
const char* url = "testurl";
entry.setFieldVL(ripple::sfURI, ripple::Slice(url, 7));
NFTArray1.push_back(entry);
auto entry2 = ripple::STObject(ripple::sfNFToken);
entry2.setFieldH256(ripple::sfNFTokenID, ripple::uint256{INDEX1});
entry2.setFieldVL(ripple::sfURI, ripple::Slice(url, 7));
NFTArray1.push_back(entry2);
finalFields.setFieldArray(ripple::sfNFTokens, NFTArray1);
NFTArray1.erase(NFTArray1.begin());
ripple::STObject previousFields(ripple::sfPreviousFields);
previousFields.setFieldArray(ripple::sfNFTokens, NFTArray1);
node.emplace_back(std::move(finalFields));
node.emplace_back(std::move(previousFields));
metaArray.push_back(node);
metaObj.setFieldArray(ripple::sfAffectedNodes, metaArray);
metaObj.setFieldU8(ripple::sfTransactionResult, ripple::tesSUCCESS);
metaObj.setFieldU32(ripple::sfTransactionIndex, 0);
Backend::TransactionAndMetadata ret;
ret.transaction = tx.getSerializer().peekData();
ret.metadata = metaObj.getSerializer().peekData();
return ret;
}
Backend::TransactionAndMetadata
CreateAcceptNFTOfferTxWithMetadata(std::string_view accountId, uint32_t seq, uint32_t fee, std::string_view nftId)
{
// tx
ripple::STObject tx(ripple::sfTransaction);
tx.setFieldU16(ripple::sfTransactionType, ripple::ttNFTOKEN_ACCEPT_OFFER);
auto account = ripple::parseBase58<ripple::AccountID>(std::string(accountId));
tx.setAccountID(ripple::sfAccount, account.value());
auto amount = ripple::STAmount(fee, false);
tx.setFieldAmount(ripple::sfFee, amount);
tx.setFieldU32(ripple::sfSequence, seq);
tx.setFieldH256(ripple::sfNFTokenBuyOffer, ripple::uint256{INDEX1});
const char* key = "test";
ripple::Slice slice(key, 4);
tx.setFieldVL(ripple::sfSigningPubKey, slice);
// meta
// create deletedNode with ltNFTOKEN_OFFER
ripple::STObject metaObj(ripple::sfTransactionMetaData);
ripple::STArray metaArray{1};
ripple::STObject node(ripple::sfDeletedNode);
node.setFieldU16(ripple::sfLedgerEntryType, ripple::ltNFTOKEN_OFFER);
ripple::STObject finalFields(ripple::sfFinalFields);
finalFields.setFieldH256(ripple::sfNFTokenID, ripple::uint256{nftId});
node.emplace_back(std::move(finalFields));
metaArray.push_back(node);
metaObj.setFieldArray(ripple::sfAffectedNodes, metaArray);
metaObj.setFieldU8(ripple::sfTransactionResult, ripple::tesSUCCESS);
metaObj.setFieldU32(ripple::sfTransactionIndex, 0);
Backend::TransactionAndMetadata ret;
ret.transaction = tx.getSerializer().peekData();
ret.metadata = metaObj.getSerializer().peekData();
return ret;
}
// NFTokenCancelOffer can be used to cancel multiple offers
Backend::TransactionAndMetadata
CreateCancelNFTOffersTxWithMetadata(
std::string_view accountId,
uint32_t seq,
uint32_t fee,
std::vector<std::string> const& nftOffers)
{
// tx
ripple::STObject tx(ripple::sfTransaction);
tx.setFieldU16(ripple::sfTransactionType, ripple::ttNFTOKEN_CANCEL_OFFER);
auto account = ripple::parseBase58<ripple::AccountID>(std::string(accountId));
tx.setAccountID(ripple::sfAccount, account.value());
auto amount = ripple::STAmount(fee, false);
tx.setFieldAmount(ripple::sfFee, amount);
tx.setFieldU32(ripple::sfSequence, seq);
ripple::STVector256 offers;
offers.resize(2);
std::transform(nftOffers.cbegin(), nftOffers.cend(), offers.begin(), [&](auto const& nftId) {
return ripple::uint256{nftId.c_str()};
});
tx.setFieldV256(ripple::sfNFTokenOffers, offers);
const char* key = "test";
ripple::Slice slice(key, 4);
tx.setFieldVL(ripple::sfSigningPubKey, slice);
// meta
// create deletedNode with ltNFTOKEN_OFFER
// reuse the offer id as nft id
ripple::STObject metaObj(ripple::sfTransactionMetaData);
ripple::STArray metaArray{nftOffers.size()};
for (auto const& nftId : nftOffers)
{
ripple::STObject node(ripple::sfDeletedNode);
node.setFieldU16(ripple::sfLedgerEntryType, ripple::ltNFTOKEN_OFFER);
ripple::STObject finalFields(ripple::sfFinalFields);
finalFields.setFieldH256(ripple::sfNFTokenID, ripple::uint256{nftId.c_str()});
node.emplace_back(std::move(finalFields));
metaArray.push_back(node);
}
metaObj.setFieldArray(ripple::sfAffectedNodes, metaArray);
metaObj.setFieldU8(ripple::sfTransactionResult, ripple::tesSUCCESS);
metaObj.setFieldU32(ripple::sfTransactionIndex, 0);
Backend::TransactionAndMetadata ret;
ret.transaction = tx.getSerializer().peekData();
ret.metadata = metaObj.getSerializer().peekData();
return ret;
}
Backend::TransactionAndMetadata
CreateCreateNFTOfferTxWithMetadata(
std::string_view accountId,
uint32_t seq,
uint32_t fee,
std::string_view nftId,
std::uint32_t offerPrice,
std::string_view offerId)
{
// tx
ripple::STObject tx(ripple::sfTransaction);
tx.setFieldU16(ripple::sfTransactionType, ripple::ttNFTOKEN_CREATE_OFFER);
auto account = ripple::parseBase58<ripple::AccountID>(std::string(accountId));
tx.setAccountID(ripple::sfAccount, account.value());
auto amount = ripple::STAmount(fee, false);
tx.setFieldAmount(ripple::sfFee, amount);
auto price = ripple::STAmount(offerPrice, false);
tx.setFieldAmount(ripple::sfAmount, price);
tx.setFieldU32(ripple::sfSequence, seq);
tx.setFieldH256(ripple::sfNFTokenID, ripple::uint256{nftId});
const char* key = "test";
ripple::Slice slice(key, 4);
tx.setFieldVL(ripple::sfSigningPubKey, slice);
// meta
// create createdNode with LedgerIndex
ripple::STObject metaObj(ripple::sfTransactionMetaData);
ripple::STArray metaArray{1};
ripple::STObject node(ripple::sfCreatedNode);
node.setFieldU16(ripple::sfLedgerEntryType, ripple::ltNFTOKEN_OFFER);
node.setFieldH256(ripple::sfLedgerIndex, ripple::uint256{offerId});
metaArray.push_back(node);
metaObj.setFieldArray(ripple::sfAffectedNodes, metaArray);
metaObj.setFieldU8(ripple::sfTransactionResult, ripple::tesSUCCESS);
metaObj.setFieldU32(ripple::sfTransactionIndex, 0);
Backend::TransactionAndMetadata ret;
ret.transaction = tx.getSerializer().peekData();
ret.metadata = metaObj.getSerializer().peekData();
return ret;
}