mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Compare commits
6 Commits
2024.4.21-
...
fix-delive
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eaaab2309c | ||
|
|
849a4435e0 | ||
|
|
247e9d98bf | ||
|
|
dde03634f8 | ||
|
|
49b766181b | ||
|
|
75ab16e989 |
22
.github/workflows/build-in-docker.yml
vendored
22
.github/workflows/build-in-docker.yml
vendored
@@ -2,25 +2,37 @@ name: Build using Docker
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ "dev", "candidate", "release" ]
|
branches: [ "dev", "candidate", "release", "jshooks" ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "dev", "candidate", "release" ]
|
branches: [ "dev", "candidate", "release", "jshooks" ]
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: false
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
builder:
|
checkout:
|
||||||
runs-on: [self-hosted, vanity]
|
runs-on: [self-hosted, vanity]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
clean: false
|
clean: false
|
||||||
|
checkpatterns:
|
||||||
|
runs-on: [self-hosted, vanity]
|
||||||
|
needs: checkout
|
||||||
|
steps:
|
||||||
- name: Check for suspicious patterns
|
- name: Check for suspicious patterns
|
||||||
run: /bin/bash suspicious_patterns.sh
|
run: /bin/bash suspicious_patterns.sh
|
||||||
|
build:
|
||||||
|
runs-on: [self-hosted, vanity]
|
||||||
|
needs: checkpatterns
|
||||||
|
steps:
|
||||||
- name: Build using Docker
|
- name: Build using Docker
|
||||||
run: /bin/bash release-builder.sh
|
run: /bin/bash release-builder.sh
|
||||||
|
tests:
|
||||||
|
runs-on: [self-hosted, vanity]
|
||||||
|
needs: build
|
||||||
|
steps:
|
||||||
- name: Unit tests
|
- name: Unit tests
|
||||||
run: /bin/bash docker-unit-tests.sh
|
run: /bin/bash docker-unit-tests.sh
|
||||||
|
|
||||||
|
|||||||
@@ -61,22 +61,7 @@ getDeliveredAmount(
|
|||||||
|
|
||||||
if (serializedTx->isFieldPresent(sfAmount))
|
if (serializedTx->isFieldPresent(sfAmount))
|
||||||
{
|
{
|
||||||
using namespace std::chrono_literals;
|
return serializedTx->getFieldAmount(sfAmount);
|
||||||
|
|
||||||
// Ledger 4594095 is the first ledger in which the DeliveredAmount field
|
|
||||||
// was present when a partial payment was made and its absence indicates
|
|
||||||
// that the amount delivered is listed in the Amount field.
|
|
||||||
//
|
|
||||||
// If the ledger closed long after the DeliveredAmount code was deployed
|
|
||||||
// then its absence indicates that the amount delivered is listed in the
|
|
||||||
// Amount field. DeliveredAmount went live January 24, 2014.
|
|
||||||
// 446000000 is in Feb 2014, well after DeliveredAmount went live
|
|
||||||
if (getLedgerIndex() >= 4594095 ||
|
|
||||||
getCloseTime() > NetClock::time_point{446000000s} ||
|
|
||||||
(serializedTx && serializedTx->isFieldPresent(sfNetworkID)))
|
|
||||||
{
|
|
||||||
return serializedTx->getFieldAmount(sfAmount);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
|||||||
@@ -5466,6 +5466,7 @@ private:
|
|||||||
params[jss::transaction] = txIds[i];
|
params[jss::transaction] = txIds[i];
|
||||||
auto const jrr = env.rpc("json", "tx", to_string(params));
|
auto const jrr = env.rpc("json", "tx", to_string(params));
|
||||||
auto const meta = jrr[jss::result][jss::meta];
|
auto const meta = jrr[jss::result][jss::meta];
|
||||||
|
BEAST_EXPECT(meta[jss::delivered_amount] == "1000000");
|
||||||
for (auto const& node : meta[sfAffectedNodes.jsonName])
|
for (auto const& node : meta[sfAffectedNodes.jsonName])
|
||||||
{
|
{
|
||||||
auto const nodeType = node[sfLedgerEntryType.jsonName];
|
auto const nodeType = node[sfLedgerEntryType.jsonName];
|
||||||
|
|||||||
@@ -191,80 +191,73 @@ class DeliveredAmount_test : public beast::unit_test::suite
|
|||||||
auto const gw = Account("gateway");
|
auto const gw = Account("gateway");
|
||||||
auto const USD = gw["USD"];
|
auto const USD = gw["USD"];
|
||||||
|
|
||||||
for (bool const afterSwitchTime : {true, false})
|
Env env{*this, features};
|
||||||
|
env.fund(XRP(10000), alice, bob, carol, gw);
|
||||||
|
env.trust(USD(1000), alice, bob, carol);
|
||||||
|
env.close();
|
||||||
|
|
||||||
|
CheckDeliveredAmount checkDeliveredAmount{true};
|
||||||
{
|
{
|
||||||
Env env{*this, features};
|
// add payments, but do no close until subscribed
|
||||||
env.fund(XRP(10000), alice, bob, carol, gw);
|
|
||||||
env.trust(USD(1000), alice, bob, carol);
|
|
||||||
if (afterSwitchTime)
|
|
||||||
env.close(NetClock::time_point{446000000s});
|
|
||||||
else
|
|
||||||
env.close();
|
|
||||||
|
|
||||||
CheckDeliveredAmount checkDeliveredAmount{afterSwitchTime};
|
// normal payments
|
||||||
{
|
env(pay(gw, alice, USD(50)));
|
||||||
// add payments, but do no close until subscribed
|
checkDeliveredAmount.adjCountersSuccess();
|
||||||
|
env(pay(gw, alice, XRP(50)));
|
||||||
|
checkDeliveredAmount.adjCountersSuccess();
|
||||||
|
|
||||||
// normal payments
|
// partial payment
|
||||||
env(pay(gw, alice, USD(50)));
|
env(pay(gw, bob, USD(9999999)), txflags(tfPartialPayment));
|
||||||
checkDeliveredAmount.adjCountersSuccess();
|
checkDeliveredAmount.adjCountersPartialPayment();
|
||||||
env(pay(gw, alice, XRP(50)));
|
env.require(balance(bob, USD(1000)));
|
||||||
checkDeliveredAmount.adjCountersSuccess();
|
|
||||||
|
|
||||||
// partial payment
|
// failed payment
|
||||||
env(pay(gw, bob, USD(9999999)), txflags(tfPartialPayment));
|
env(pay(bob, carol, USD(9999999)), ter(tecPATH_PARTIAL));
|
||||||
checkDeliveredAmount.adjCountersPartialPayment();
|
checkDeliveredAmount.adjCountersFail();
|
||||||
env.require(balance(bob, USD(1000)));
|
env.require(balance(carol, USD(0)));
|
||||||
|
|
||||||
// failed payment
|
|
||||||
env(pay(bob, carol, USD(9999999)), ter(tecPATH_PARTIAL));
|
|
||||||
checkDeliveredAmount.adjCountersFail();
|
|
||||||
env.require(balance(carol, USD(0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto wsc = makeWSClient(env.app().config());
|
|
||||||
|
|
||||||
{
|
|
||||||
Json::Value stream;
|
|
||||||
// RPC subscribe to ledger stream
|
|
||||||
stream[jss::streams] = Json::arrayValue;
|
|
||||||
stream[jss::streams].append("ledger");
|
|
||||||
stream[jss::accounts] = Json::arrayValue;
|
|
||||||
stream[jss::accounts].append(toBase58(alice.id()));
|
|
||||||
stream[jss::accounts].append(toBase58(bob.id()));
|
|
||||||
stream[jss::accounts].append(toBase58(carol.id()));
|
|
||||||
auto jv = wsc->invoke("subscribe", stream);
|
|
||||||
if (wsc->version() == 2)
|
|
||||||
{
|
|
||||||
BEAST_EXPECT(
|
|
||||||
jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] == "2.0");
|
|
||||||
BEAST_EXPECT(
|
|
||||||
jv.isMember(jss::ripplerpc) &&
|
|
||||||
jv[jss::ripplerpc] == "2.0");
|
|
||||||
BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
|
|
||||||
}
|
|
||||||
BEAST_EXPECT(jv[jss::result][jss::ledger_index] == 3);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
env.close();
|
|
||||||
// Check stream update
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
auto const r = wsc->findMsg(1s, [&](auto const& jv) {
|
|
||||||
return jv[jss::ledger_index] == 4;
|
|
||||||
});
|
|
||||||
if (!r)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!r->isMember(jss::transaction))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
BEAST_EXPECT(checkDeliveredAmount.checkTxn(
|
|
||||||
(*r)[jss::transaction], (*r)[jss::meta]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BEAST_EXPECT(checkDeliveredAmount.checkExpectedCounters());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto wsc = makeWSClient(env.app().config());
|
||||||
|
|
||||||
|
{
|
||||||
|
Json::Value stream;
|
||||||
|
// RPC subscribe to ledger stream
|
||||||
|
stream[jss::streams] = Json::arrayValue;
|
||||||
|
stream[jss::streams].append("ledger");
|
||||||
|
stream[jss::accounts] = Json::arrayValue;
|
||||||
|
stream[jss::accounts].append(toBase58(alice.id()));
|
||||||
|
stream[jss::accounts].append(toBase58(bob.id()));
|
||||||
|
stream[jss::accounts].append(toBase58(carol.id()));
|
||||||
|
auto jv = wsc->invoke("subscribe", stream);
|
||||||
|
if (wsc->version() == 2)
|
||||||
|
{
|
||||||
|
BEAST_EXPECT(
|
||||||
|
jv.isMember(jss::jsonrpc) && jv[jss::jsonrpc] == "2.0");
|
||||||
|
BEAST_EXPECT(
|
||||||
|
jv.isMember(jss::ripplerpc) && jv[jss::ripplerpc] == "2.0");
|
||||||
|
BEAST_EXPECT(jv.isMember(jss::id) && jv[jss::id] == 5);
|
||||||
|
}
|
||||||
|
BEAST_EXPECT(jv[jss::result][jss::ledger_index] == 3);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
env.close();
|
||||||
|
// Check stream update
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
auto const r = wsc->findMsg(1s, [&](auto const& jv) {
|
||||||
|
return jv[jss::ledger_index] == 4;
|
||||||
|
});
|
||||||
|
if (!r)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!r->isMember(jss::transaction))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BEAST_EXPECT(checkDeliveredAmount.checkTxn(
|
||||||
|
(*r)[jss::transaction], (*r)[jss::meta]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BEAST_EXPECT(checkDeliveredAmount.checkExpectedCounters());
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
testTxDeliveredAmountRPC(FeatureBitset features)
|
testTxDeliveredAmountRPC(FeatureBitset features)
|
||||||
@@ -280,49 +273,41 @@ class DeliveredAmount_test : public beast::unit_test::suite
|
|||||||
auto const gw = Account("gateway");
|
auto const gw = Account("gateway");
|
||||||
auto const USD = gw["USD"];
|
auto const USD = gw["USD"];
|
||||||
|
|
||||||
for (bool const afterSwitchTime : {true, false})
|
Env env{*this, features};
|
||||||
{
|
env.fund(XRP(10000), alice, bob, carol, gw);
|
||||||
Env env{*this, features};
|
env.trust(USD(1000), alice, bob, carol);
|
||||||
env.fund(XRP(10000), alice, bob, carol, gw);
|
env.close();
|
||||||
env.trust(USD(1000), alice, bob, carol);
|
|
||||||
if (afterSwitchTime)
|
|
||||||
env.close(NetClock::time_point{446000000s});
|
|
||||||
else
|
|
||||||
env.close();
|
|
||||||
|
|
||||||
CheckDeliveredAmount checkDeliveredAmount{afterSwitchTime};
|
CheckDeliveredAmount checkDeliveredAmount{true};
|
||||||
// normal payments
|
// normal payments
|
||||||
env(pay(gw, alice, USD(50)));
|
env(pay(gw, alice, USD(50)));
|
||||||
checkDeliveredAmount.adjCountersSuccess();
|
checkDeliveredAmount.adjCountersSuccess();
|
||||||
env(pay(gw, alice, XRP(50)));
|
env(pay(gw, alice, XRP(50)));
|
||||||
checkDeliveredAmount.adjCountersSuccess();
|
checkDeliveredAmount.adjCountersSuccess();
|
||||||
|
|
||||||
// partial payment
|
// partial payment
|
||||||
env(pay(gw, bob, USD(9999999)), txflags(tfPartialPayment));
|
env(pay(gw, bob, USD(9999999)), txflags(tfPartialPayment));
|
||||||
checkDeliveredAmount.adjCountersPartialPayment();
|
checkDeliveredAmount.adjCountersPartialPayment();
|
||||||
env.require(balance(bob, USD(1000)));
|
env.require(balance(bob, USD(1000)));
|
||||||
|
|
||||||
// failed payment
|
// failed payment
|
||||||
env(pay(gw, carol, USD(9999999)), ter(tecPATH_PARTIAL));
|
env(pay(gw, carol, USD(9999999)), ter(tecPATH_PARTIAL));
|
||||||
checkDeliveredAmount.adjCountersFail();
|
checkDeliveredAmount.adjCountersFail();
|
||||||
env.require(balance(carol, USD(0)));
|
env.require(balance(carol, USD(0)));
|
||||||
|
|
||||||
env.close();
|
env.close();
|
||||||
std::string index;
|
std::string index;
|
||||||
Json::Value jvParams;
|
Json::Value jvParams;
|
||||||
jvParams[jss::ledger_index] = 4u;
|
jvParams[jss::ledger_index] = 4u;
|
||||||
jvParams[jss::transactions] = true;
|
jvParams[jss::transactions] = true;
|
||||||
jvParams[jss::expand] = true;
|
jvParams[jss::expand] = true;
|
||||||
auto const jtxn = env.rpc(
|
auto const jtxn = env.rpc(
|
||||||
"json",
|
"json",
|
||||||
"ledger",
|
"ledger",
|
||||||
to_string(
|
to_string(jvParams))[jss::result][jss::ledger][jss::transactions];
|
||||||
jvParams))[jss::result][jss::ledger][jss::transactions];
|
for (auto const& t : jtxn)
|
||||||
for (auto const& t : jtxn)
|
BEAST_EXPECT(checkDeliveredAmount.checkTxn(t, t[jss::metaData]));
|
||||||
BEAST_EXPECT(
|
BEAST_EXPECT(checkDeliveredAmount.checkExpectedCounters());
|
||||||
checkDeliveredAmount.checkTxn(t, t[jss::metaData]));
|
|
||||||
BEAST_EXPECT(checkDeliveredAmount.checkExpectedCounters());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ public:
|
|||||||
{
|
{
|
||||||
Env env(*this);
|
Env env(*this);
|
||||||
auto const result = env.rpc("server_definitions");
|
auto const result = env.rpc("server_definitions");
|
||||||
std::cout << "RESULT: " << result << "\n";
|
|
||||||
BEAST_EXPECT(!result[jss::result].isMember(jss::error));
|
BEAST_EXPECT(!result[jss::result].isMember(jss::error));
|
||||||
BEAST_EXPECT(result[jss::result].isMember(jss::FIELDS));
|
BEAST_EXPECT(result[jss::result].isMember(jss::FIELDS));
|
||||||
BEAST_EXPECT(result[jss::result].isMember(jss::LEDGER_ENTRY_TYPES));
|
BEAST_EXPECT(result[jss::result].isMember(jss::LEDGER_ENTRY_TYPES));
|
||||||
|
|||||||
Reference in New Issue
Block a user