mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 11:05:54 +00:00
Merge branch 'ripple/smart-escrow' into develop2
This commit is contained in:
@@ -18,6 +18,7 @@
|
|||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
#include <xrpld/app/misc/WasmHostFuncImpl.h>
|
#include <xrpld/app/misc/WasmHostFuncImpl.h>
|
||||||
|
#include <xrpld/app/tx/detail/NFTokenUtils.h>
|
||||||
|
|
||||||
#include <xrpl/protocol/digest.h>
|
#include <xrpl/protocol/digest.h>
|
||||||
|
|
||||||
@@ -98,6 +99,33 @@ WasmHostFunctionsImpl::getCurrentLedgerEntryField(const std::string& fname)
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<Bytes>
|
||||||
|
WasmHostFunctionsImpl::getNFT(
|
||||||
|
const std::string& account,
|
||||||
|
const std::string& nftId)
|
||||||
|
{
|
||||||
|
auto const accountId = parseBase58<AccountID>(account);
|
||||||
|
if (!accountId || accountId->isZero())
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint256 nftHash;
|
||||||
|
if (!nftHash.parseHex(nftId))
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto jv = nft::findToken(ctx.view(), accountId.value(), nftHash);
|
||||||
|
if (!jv)
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
Slice const s = (*jv)[sfURI];
|
||||||
|
return Bytes{s.begin(), s.end()};
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
WasmHostFunctionsImpl::updateData(const Bytes& data)
|
WasmHostFunctionsImpl::updateData(const Bytes& data)
|
||||||
{
|
{
|
||||||
@@ -115,4 +143,91 @@ WasmHostFunctionsImpl::computeSha512HalfHash(const Bytes& data)
|
|||||||
auto const hash = sha512Half(data);
|
auto const hash = sha512Half(data);
|
||||||
return uint256::fromVoid(hash.data());
|
return uint256::fromVoid(hash.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<Bytes>
|
||||||
|
WasmHostFunctionsImpl::accountKeylet(const std::string& account)
|
||||||
|
{
|
||||||
|
auto const accountId = parseBase58<AccountID>(account);
|
||||||
|
if (!accountId || accountId->isZero())
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto keylet = keylet::account(*accountId).key;
|
||||||
|
if (!keylet)
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Bytes{keylet.begin(), keylet.end()};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<Bytes>
|
||||||
|
WasmHostFunctionsImpl::credentialKeylet(
|
||||||
|
const std::string& subject,
|
||||||
|
const std::string& issuer,
|
||||||
|
const std::string& credentialType)
|
||||||
|
{
|
||||||
|
auto const subjectId = parseBase58<AccountID>(subject);
|
||||||
|
if (!subjectId || subjectId->isZero())
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const issuerId = parseBase58<AccountID>(issuer);
|
||||||
|
if (!issuerId || issuerId->isZero())
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto keylet =
|
||||||
|
keylet::credential(*subjectId, *issuerId, makeSlice(credentialType))
|
||||||
|
.key;
|
||||||
|
if (!keylet)
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Bytes{keylet.begin(), keylet.end()};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<Bytes>
|
||||||
|
WasmHostFunctionsImpl::escrowKeylet(
|
||||||
|
const std::string& account,
|
||||||
|
const std::uint32_t& seq)
|
||||||
|
{
|
||||||
|
auto const accountId = parseBase58<AccountID>(account);
|
||||||
|
if (!accountId || accountId->isZero())
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto keylet = keylet::escrow(*accountId, seq).key;
|
||||||
|
if (!keylet)
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Bytes{keylet.begin(), keylet.end()};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<Bytes>
|
||||||
|
WasmHostFunctionsImpl::oracleKeylet(
|
||||||
|
const std::string& account,
|
||||||
|
const std::uint32_t& documentId)
|
||||||
|
{
|
||||||
|
auto const accountId = parseBase58<AccountID>(account);
|
||||||
|
if (!accountId || accountId->isZero())
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto keylet = keylet::oracle(*accountId, documentId).key;
|
||||||
|
if (!keylet)
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Bytes{keylet.begin(), keylet.end()};
|
||||||
|
}
|
||||||
} // namespace ripple
|
} // namespace ripple
|
||||||
|
|||||||
@@ -54,12 +54,31 @@ public:
|
|||||||
std::optional<Bytes>
|
std::optional<Bytes>
|
||||||
getCurrentLedgerEntryField(std::string const& fname) override;
|
getCurrentLedgerEntryField(std::string const& fname) override;
|
||||||
|
|
||||||
|
std::optional<Bytes>
|
||||||
|
getNFT(std::string const& account, std::string const& nftId) override;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
updateData(Bytes const& data) override;
|
updateData(Bytes const& data) override;
|
||||||
|
|
||||||
Hash
|
Hash
|
||||||
computeSha512HalfHash(Bytes const& data) override;
|
computeSha512HalfHash(Bytes const& data) override;
|
||||||
|
|
||||||
|
std::optional<Bytes>
|
||||||
|
accountKeylet(std::string const& account) override;
|
||||||
|
|
||||||
|
std::optional<Bytes>
|
||||||
|
credentialKeylet(
|
||||||
|
std::string const& subject,
|
||||||
|
std::string const& issuer,
|
||||||
|
std::string const& credentialType) override;
|
||||||
|
|
||||||
|
std::optional<Bytes>
|
||||||
|
escrowKeylet(std::string const& account, std::uint32_t const& seq) override;
|
||||||
|
|
||||||
|
std::optional<Bytes>
|
||||||
|
oracleKeylet(std::string const& account, std::uint32_t const& documentId)
|
||||||
|
override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ApplyContext& ctx;
|
ApplyContext& ctx;
|
||||||
Keylet leKey;
|
Keylet leKey;
|
||||||
|
|||||||
@@ -220,6 +220,148 @@ getCurrentLedgerEntryField(
|
|||||||
return WasmEdge_Result_Success;
|
return WasmEdge_Result_Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WasmEdge_Result
|
||||||
|
getNFT(
|
||||||
|
void* data,
|
||||||
|
const WasmEdge_CallingFrameContext* fm,
|
||||||
|
const WasmEdge_Value* in,
|
||||||
|
WasmEdge_Value* out)
|
||||||
|
{
|
||||||
|
auto account = getFieldName(fm, in, 0);
|
||||||
|
if (!account)
|
||||||
|
return account.error();
|
||||||
|
|
||||||
|
auto nftId = getFieldName(fm, in, 2);
|
||||||
|
if (!nftId)
|
||||||
|
return nftId.error();
|
||||||
|
|
||||||
|
auto nftURI =
|
||||||
|
((HostFunctions*)data)->getNFT(account.value(), nftId.value());
|
||||||
|
if (!nftURI)
|
||||||
|
return WasmEdge_Result_Fail;
|
||||||
|
|
||||||
|
auto pointer = setData(fm, nftURI.value());
|
||||||
|
if (!pointer)
|
||||||
|
return pointer.error();
|
||||||
|
|
||||||
|
out[0] = pointer.value();
|
||||||
|
// out[1] = WasmEdge_ValueGenI32((int)nftURI.value().size());
|
||||||
|
return WasmEdge_Result_Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
WasmEdge_Result
|
||||||
|
accountKeylet(
|
||||||
|
void* data,
|
||||||
|
const WasmEdge_CallingFrameContext* fm,
|
||||||
|
const WasmEdge_Value* in,
|
||||||
|
WasmEdge_Value* out)
|
||||||
|
{
|
||||||
|
auto account = getFieldName(fm, in, 0);
|
||||||
|
if (!account)
|
||||||
|
return account.error();
|
||||||
|
|
||||||
|
auto keylet = ((HostFunctions*)data)->accountKeylet(account.value());
|
||||||
|
if (!keylet)
|
||||||
|
return WasmEdge_Result_Fail;
|
||||||
|
|
||||||
|
auto pointer = setData(fm, keylet.value());
|
||||||
|
if (!pointer)
|
||||||
|
return pointer.error();
|
||||||
|
|
||||||
|
out[0] = pointer.value();
|
||||||
|
// out[1] = WasmEdge_ValueGenI32((int)nftURI.value().size());
|
||||||
|
return WasmEdge_Result_Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
WasmEdge_Result
|
||||||
|
credentialKeylet(
|
||||||
|
void* data,
|
||||||
|
const WasmEdge_CallingFrameContext* fm,
|
||||||
|
const WasmEdge_Value* in,
|
||||||
|
WasmEdge_Value* out)
|
||||||
|
{
|
||||||
|
auto subject = getFieldName(fm, in, 0);
|
||||||
|
if (!subject)
|
||||||
|
return subject.error();
|
||||||
|
|
||||||
|
auto issuer = getFieldName(fm, in, 2);
|
||||||
|
if (!issuer)
|
||||||
|
return issuer.error();
|
||||||
|
|
||||||
|
auto credentialType = getFieldName(fm, in, 4);
|
||||||
|
if (!credentialType)
|
||||||
|
return credentialType.error();
|
||||||
|
|
||||||
|
auto keylet =
|
||||||
|
((HostFunctions*)data)
|
||||||
|
->credentialKeylet(
|
||||||
|
subject.value(), issuer.value(), credentialType.value());
|
||||||
|
if (!keylet)
|
||||||
|
return WasmEdge_Result_Fail;
|
||||||
|
|
||||||
|
auto pointer = setData(fm, keylet.value());
|
||||||
|
if (!pointer)
|
||||||
|
return pointer.error();
|
||||||
|
|
||||||
|
out[0] = pointer.value();
|
||||||
|
// out[1] = WasmEdge_ValueGenI32((int)nftURI.value().size());
|
||||||
|
return WasmEdge_Result_Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
WasmEdge_Result
|
||||||
|
escrowKeylet(
|
||||||
|
void* data,
|
||||||
|
const WasmEdge_CallingFrameContext* fm,
|
||||||
|
const WasmEdge_Value* in,
|
||||||
|
WasmEdge_Value* out)
|
||||||
|
{
|
||||||
|
auto account = getFieldName(fm, in, 0);
|
||||||
|
if (!account)
|
||||||
|
return account.error();
|
||||||
|
|
||||||
|
auto sequence = WasmEdge_ValueGetI32(in[2]);
|
||||||
|
|
||||||
|
auto keylet =
|
||||||
|
((HostFunctions*)data)->escrowKeylet(account.value(), sequence);
|
||||||
|
if (!keylet)
|
||||||
|
return WasmEdge_Result_Fail;
|
||||||
|
|
||||||
|
auto pointer = setData(fm, keylet.value());
|
||||||
|
if (!pointer)
|
||||||
|
return pointer.error();
|
||||||
|
|
||||||
|
out[0] = pointer.value();
|
||||||
|
// out[1] = WasmEdge_ValueGenI32((int)nftURI.value().size());
|
||||||
|
return WasmEdge_Result_Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
WasmEdge_Result
|
||||||
|
oracleKeylet(
|
||||||
|
void* data,
|
||||||
|
const WasmEdge_CallingFrameContext* fm,
|
||||||
|
const WasmEdge_Value* in,
|
||||||
|
WasmEdge_Value* out)
|
||||||
|
{
|
||||||
|
auto account = getFieldName(fm, in, 0);
|
||||||
|
if (!account)
|
||||||
|
return account.error();
|
||||||
|
|
||||||
|
auto documentId = WasmEdge_ValueGetI32(in[2]);
|
||||||
|
|
||||||
|
auto keylet =
|
||||||
|
((HostFunctions*)data)->escrowKeylet(account.value(), documentId);
|
||||||
|
if (!keylet)
|
||||||
|
return WasmEdge_Result_Fail;
|
||||||
|
|
||||||
|
auto pointer = setData(fm, keylet.value());
|
||||||
|
if (!pointer)
|
||||||
|
return pointer.error();
|
||||||
|
|
||||||
|
out[0] = pointer.value();
|
||||||
|
// out[1] = WasmEdge_ValueGenI32((int)nftURI.value().size());
|
||||||
|
return WasmEdge_Result_Success;
|
||||||
|
}
|
||||||
|
|
||||||
WasmEdge_Result
|
WasmEdge_Result
|
||||||
updateData(
|
updateData(
|
||||||
void* data,
|
void* data,
|
||||||
@@ -393,6 +535,25 @@ runEscrowWasm(
|
|||||||
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
|
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
|
||||||
// WasmEdge_StringDelete(fName);
|
// WasmEdge_StringDelete(fName);
|
||||||
}
|
}
|
||||||
|
// getNFT
|
||||||
|
{
|
||||||
|
WasmEdge_ValType inputList[4] = {
|
||||||
|
WasmEdge_ValTypeGenI32(),
|
||||||
|
WasmEdge_ValTypeGenI32(),
|
||||||
|
WasmEdge_ValTypeGenI32(),
|
||||||
|
WasmEdge_ValTypeGenI32()};
|
||||||
|
WasmEdge_ValType returnList[1] = {WasmEdge_ValTypeGenI32()};
|
||||||
|
WasmEdge_FunctionTypeContext* hostFuncType =
|
||||||
|
WasmEdge_FunctionTypeCreate(inputList, 2, returnList, 1);
|
||||||
|
WasmEdge_FunctionInstanceContext* hostFunc =
|
||||||
|
WasmEdge_FunctionInstanceCreate(hostFuncType, getNFT, hfs, 100);
|
||||||
|
// WasmEdge_FunctionTypeDelete(hostFuncType);
|
||||||
|
// WasmEdge_FunctionInstanceDelete(hostFunc);
|
||||||
|
|
||||||
|
WasmEdge_String fName = WasmEdge_StringCreateByCString("getNFT");
|
||||||
|
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
|
||||||
|
// WasmEdge_StringDelete(fName);
|
||||||
|
}
|
||||||
// updateData
|
// updateData
|
||||||
{
|
{
|
||||||
WasmEdge_ValType inputList[2] = {
|
WasmEdge_ValType inputList[2] = {
|
||||||
@@ -428,6 +589,86 @@ runEscrowWasm(
|
|||||||
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
|
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
|
||||||
// WasmEdge_StringDelete(fName);
|
// WasmEdge_StringDelete(fName);
|
||||||
}
|
}
|
||||||
|
// accountKeylet
|
||||||
|
{
|
||||||
|
WasmEdge_ValType inputList[2] = {
|
||||||
|
WasmEdge_ValTypeGenI32(), WasmEdge_ValTypeGenI32()};
|
||||||
|
WasmEdge_ValType returnList[1] = {WasmEdge_ValTypeGenI32()};
|
||||||
|
WasmEdge_FunctionTypeContext* hostFuncType =
|
||||||
|
WasmEdge_FunctionTypeCreate(inputList, 2, returnList, 1);
|
||||||
|
WasmEdge_FunctionInstanceContext* hostFunc =
|
||||||
|
WasmEdge_FunctionInstanceCreate(
|
||||||
|
hostFuncType, accountKeylet, hfs, 100);
|
||||||
|
// WasmEdge_FunctionTypeDelete(hostFuncType);
|
||||||
|
// WasmEdge_FunctionInstanceDelete(hostFunc);
|
||||||
|
|
||||||
|
WasmEdge_String fName =
|
||||||
|
WasmEdge_StringCreateByCString("accountKeylet");
|
||||||
|
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
|
||||||
|
// WasmEdge_StringDelete(fName);
|
||||||
|
}
|
||||||
|
// credentialKeylet
|
||||||
|
{
|
||||||
|
WasmEdge_ValType inputList[6] = {
|
||||||
|
WasmEdge_ValTypeGenI32(),
|
||||||
|
WasmEdge_ValTypeGenI32(),
|
||||||
|
WasmEdge_ValTypeGenI32(),
|
||||||
|
WasmEdge_ValTypeGenI32(),
|
||||||
|
WasmEdge_ValTypeGenI32(),
|
||||||
|
WasmEdge_ValTypeGenI32()};
|
||||||
|
WasmEdge_ValType returnList[1] = {WasmEdge_ValTypeGenI32()};
|
||||||
|
WasmEdge_FunctionTypeContext* hostFuncType =
|
||||||
|
WasmEdge_FunctionTypeCreate(inputList, 6, returnList, 1);
|
||||||
|
WasmEdge_FunctionInstanceContext* hostFunc =
|
||||||
|
WasmEdge_FunctionInstanceCreate(
|
||||||
|
hostFuncType, credentialKeylet, hfs, 100);
|
||||||
|
// WasmEdge_FunctionTypeDelete(hostFuncType);
|
||||||
|
// WasmEdge_FunctionInstanceDelete(hostFunc);
|
||||||
|
WasmEdge_String fName =
|
||||||
|
WasmEdge_StringCreateByCString("credentialKeylet");
|
||||||
|
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
|
||||||
|
// WasmEdge_StringDelete(fName);
|
||||||
|
}
|
||||||
|
// escrowKeylet
|
||||||
|
{
|
||||||
|
WasmEdge_ValType inputList[3] = {
|
||||||
|
WasmEdge_ValTypeGenI32(),
|
||||||
|
WasmEdge_ValTypeGenI32(),
|
||||||
|
WasmEdge_ValTypeGenI32()};
|
||||||
|
WasmEdge_ValType returnList[1] = {WasmEdge_ValTypeGenI32()};
|
||||||
|
WasmEdge_FunctionTypeContext* hostFuncType =
|
||||||
|
WasmEdge_FunctionTypeCreate(inputList, 3, returnList, 1);
|
||||||
|
WasmEdge_FunctionInstanceContext* hostFunc =
|
||||||
|
WasmEdge_FunctionInstanceCreate(
|
||||||
|
hostFuncType, escrowKeylet, hfs, 100);
|
||||||
|
// WasmEdge_FunctionTypeDelete(hostFuncType);
|
||||||
|
// WasmEdge_FunctionInstanceDelete(hostFunc);
|
||||||
|
|
||||||
|
WasmEdge_String fName =
|
||||||
|
WasmEdge_StringCreateByCString("escrowKeylet");
|
||||||
|
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
|
||||||
|
// WasmEdge_StringDelete(fName);
|
||||||
|
}
|
||||||
|
// oracleKeylet
|
||||||
|
{
|
||||||
|
WasmEdge_ValType inputList[3] = {
|
||||||
|
WasmEdge_ValTypeGenI32(),
|
||||||
|
WasmEdge_ValTypeGenI32(),
|
||||||
|
WasmEdge_ValTypeGenI32()};
|
||||||
|
WasmEdge_ValType returnList[1] = {WasmEdge_ValTypeGenI32()};
|
||||||
|
WasmEdge_FunctionTypeContext* hostFuncType =
|
||||||
|
WasmEdge_FunctionTypeCreate(inputList, 3, returnList, 1);
|
||||||
|
WasmEdge_FunctionInstanceContext* hostFunc =
|
||||||
|
WasmEdge_FunctionInstanceCreate(
|
||||||
|
hostFuncType, oracleKeylet, hfs, 100);
|
||||||
|
// WasmEdge_FunctionTypeDelete(hostFuncType);
|
||||||
|
// WasmEdge_FunctionInstanceDelete(hostFunc);
|
||||||
|
|
||||||
|
WasmEdge_String fName =
|
||||||
|
WasmEdge_StringCreateByCString("oracleKeylet");
|
||||||
|
WasmEdge_ModuleInstanceAddFunction(hostMod, fName, hostFunc);
|
||||||
|
// WasmEdge_StringDelete(fName);
|
||||||
|
}
|
||||||
// print
|
// print
|
||||||
{
|
{
|
||||||
WasmEdge_ValType inputList[2] = {
|
WasmEdge_ValType inputList[2] = {
|
||||||
|
|||||||
@@ -74,6 +74,12 @@ struct HostFunctions
|
|||||||
return Bytes{};
|
return Bytes{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual std::optional<Bytes>
|
||||||
|
getNFT(std::string const& account, std::string const& nftId)
|
||||||
|
{
|
||||||
|
return Bytes{};
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
updateData(Bytes const& data)
|
updateData(Bytes const& data)
|
||||||
{
|
{
|
||||||
@@ -86,6 +92,33 @@ struct HostFunctions
|
|||||||
return Hash{};
|
return Hash{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual std::optional<Bytes>
|
||||||
|
accountKeylet(std::string const& account)
|
||||||
|
{
|
||||||
|
return Bytes{};
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::optional<Bytes>
|
||||||
|
credentialKeylet(
|
||||||
|
std::string const& subject,
|
||||||
|
std::string const& issuer,
|
||||||
|
std::string const& credentialType)
|
||||||
|
{
|
||||||
|
return Bytes{};
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::optional<Bytes>
|
||||||
|
escrowKeylet(std::string const& account, std::uint32_t const& seq)
|
||||||
|
{
|
||||||
|
return Bytes{};
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::optional<Bytes>
|
||||||
|
oracleKeylet(std::string const& account, std::uint32_t const& docId)
|
||||||
|
{
|
||||||
|
return Bytes{};
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~HostFunctions() = default;
|
virtual ~HostFunctions() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user