Skip to content

Commit

Permalink
Merge pull request #14 from gradido/fix_inMemoryFindAllPagination
Browse files Browse the repository at this point in the history
Fix in memory find all pagination
  • Loading branch information
einhornimmond authored Aug 29, 2024
2 parents 46c2636 + 0dfafa7 commit fa8c4eb
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 12 deletions.
3 changes: 3 additions & 0 deletions include/gradido_blockchain/interaction/toJson/Context.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "TransactionBodyRole.h"
#include "GradidoTransactionRole.h"
#include "ConfirmedTransactionRole.h"
#include "FilterRole.h"

namespace gradido {
namespace interaction {
Expand All @@ -17,6 +18,8 @@ namespace gradido {
: mRole(std::make_unique<GradidoTransactionRole>(gradidoTransaction, format)) {}
Context(const data::ConfirmedTransaction& confirmedTransaction, BodyBytesType format = BodyBytesType::JSON)
: mRole(std::make_unique<ConfirmedTransactionRole>(confirmedTransaction, format)) {}
Context(const blockchain::Filter& filter)
: mRole(std::make_unique<FilterRole>(filter)) {}

inline std::string run(bool pretty = false) { return mRole->run(pretty);}
protected:
Expand Down
25 changes: 25 additions & 0 deletions include/gradido_blockchain/interaction/toJson/FilterRole.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef __GRADIDO_BLOCKCHAIN_INTERACTION_TO_JSON_FILTER_ROLE_H
#define __GRADIDO_BLOCKCHAIN_INTERACTION_TO_JSON_FILTER_ROLE_H

#include "gradido_blockchain/blockchain/Filter.h"
#include "AbstractRole.h"

namespace gradido {
namespace interaction {
namespace toJson {
class FilterRole : public AbstractRole
{
public:
FilterRole(const blockchain::Filter& filter)
: mFilter(filter) {}

rapidjson::Value composeJson(rapidjson::Document& rootDocument) const;

protected:
const blockchain::Filter& mFilter;
};
}
}
}

#endif //__GRADIDO_BLOCKCHAIN_INTERACTION_TO_JSON_FILTER_ROLE_H
29 changes: 17 additions & 12 deletions src/blockchain/InMemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "gradido_blockchain/const.h"
#include "gradido_blockchain/blockchain/FilterBuilder.h"

#include "gradido_blockchain/interaction/toJson/Context.h"

#include <algorithm>

namespace gradido {
Expand Down Expand Up @@ -180,8 +182,9 @@ namespace gradido {
// disable pagination for prefilter round
partFilter.pagination = Pagination();
auto prefilteredTransactions = processEntry(range.first, range.second, notYetFiltered, partFilter);
// and if a filter function exist we sort and call it in correct order
if (filter.filterFunction && !prefilteredTransactions.empty()) {

// we need to call processEntry again for filterFunction, searchDirection and/or pagination
if (!prefilteredTransactions.empty()) {
std::map<uint64_t, std::shared_ptr<TransactionEntry>> sortedTransactions;
for (std::shared_ptr<TransactionEntry> entry : prefilteredTransactions) {
sortedTransactions.insert({ entry->getTransactionNr(), entry });
Expand Down Expand Up @@ -331,17 +334,19 @@ namespace gradido {
);
if (lastFromSameSender) {
auto lastFromSameSenderBody = lastFromSameSender->getTransactionBody();
auto lastFromSameSenderRecipient = lastFromSameSenderBody->getDeferredTransfer()->getTransfer().getRecipient();

auto pubkey = body->getTransfer()->getSender().getPubkey();
if (lastFromSameSenderBody->isDeferredTransfer() &&
lastFromSameSenderRecipient->isTheSame(pubkey)) {
auto lastFromSameSenderTimeout = lastFromSameSenderBody->getDeferredTransfer()->getTimeout();
// seems we found a matching deferred transfer transaction
auto byTimeoutDeferredRedeemedPairsIt = mTimeoutDeferredRedeemedTransferPairs.equal_range(lastFromSameSenderTimeout.getAsTimepoint());
for (auto it = byTimeoutDeferredRedeemedPairsIt.first; it != byTimeoutDeferredRedeemedPairsIt.second; ++it) {
if (lastFromSameSender->getSerializedTransaction()->isTheSame(it->second.first->getSerializedTransaction())) {
it->second.second = transactionEntry;
break;
if (lastFromSameSenderBody->isDeferredTransfer()) {
auto lastFromSameSenderRecipient = lastFromSameSenderBody->getDeferredTransfer()->getTransfer().getRecipient();
if (lastFromSameSenderRecipient->isTheSame(pubkey)) {
auto lastFromSameSenderTimeout = lastFromSameSenderBody->getDeferredTransfer()->getTimeout();
// seems we found a matching deferred transfer transaction
auto byTimeoutDeferredRedeemedPairsIt = mTimeoutDeferredRedeemedTransferPairs.equal_range(lastFromSameSenderTimeout.getAsTimepoint());
for (auto it = byTimeoutDeferredRedeemedPairsIt.first; it != byTimeoutDeferredRedeemedPairsIt.second; ++it) {
if (lastFromSameSender->getSerializedTransaction()->isTheSame(it->second.first->getSerializedTransaction())) {
it->second.second = transactionEntry;
break;
}
}
}
}
Expand Down
47 changes: 47 additions & 0 deletions src/interaction/toJson/FilterRole.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "gradido_blockchain/interaction/toJson/FilterRole.h"
#include "gradido_blockchain/lib/DataTypeConverter.h"

#include "magic_enum/magic_enum.hpp"

using namespace rapidjson;
using namespace magic_enum;

namespace gradido {
namespace interaction {
namespace toJson {
Value FilterRole::composeJson(rapidjson::Document& rootDocument) const
{
Value d(kObjectType);
auto& alloc = rootDocument.GetAllocator();
d.AddMember("minTransactionNr", mFilter.minTransactionNr, alloc);
d.AddMember("maxTransactionNr", mFilter.maxTransactionNr, alloc);
if(mFilter.involvedPublicKey) {
d.AddMember("involvedPublicKey", Value(mFilter.involvedPublicKey->convertToHex().data(), alloc), alloc);
}
d.AddMember("searchDirection", Value(enum_name(mFilter.searchDirection).data(), alloc), alloc);
Value pagination(kObjectType);
pagination.AddMember("size", mFilter.pagination.size, alloc);
pagination.AddMember("page", mFilter.pagination.page, alloc);
d.AddMember("pagination", pagination, alloc);
d.AddMember("coinCommunityId", Value(mFilter.coinCommunityId.data(), alloc), alloc);

Value timepointInterval(kObjectType);
timepointInterval.AddMember(
"startDate",
Value(DataTypeConverter::timePointToString(mFilter.timepointInterval.getStartDate()).data(), alloc),
alloc
);
timepointInterval.AddMember(
"endDate",
Value(DataTypeConverter::timePointToString(mFilter.timepointInterval.getEndDate()).data(), alloc),
alloc
);
d.AddMember("timepointInterval", timepointInterval, alloc);
d.AddMember("transactionType", Value(enum_name(mFilter.transactionType).data(), alloc), alloc);

return d;
}

}
}
}
62 changes: 62 additions & 0 deletions test/blockchain/InMemoryTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,44 @@ bool InMemoryTest::createGradidoCreation(
return false;
}

bool InMemoryTest::createGradidoTransfer(
int senderKeyPairIndex,
int recipientKeyPairIndex,
GradidoUnit amount,
Timepoint createdAt
) {
assert(senderKeyPairIndex > 0 && senderKeyPairIndex < g_KeyPairs.size());
assert(recipientKeyPairIndex > 0 && recipientKeyPairIndex < g_KeyPairs.size());

TransactionBodyBuilder bodyBuilder;
bodyBuilder
.setMemo("dummy memo")
.setCreatedAt(createdAt)
.setVersionNumber(VERSION_STRING)
.setTransactionTransfer(
TransferAmount(g_KeyPairs[senderKeyPairIndex].publicKey, amount),
g_KeyPairs[recipientKeyPairIndex].publicKey
)
;
auto body = bodyBuilder.build();

serialize::Context c(*body);
auto bodyBytes = c.run();
GradidoTransactionBuilder builder;
builder
.setTransactionBody(bodyBytes)
.addSignaturePair(g_KeyPairs[senderKeyPairIndex].publicKey, sign(bodyBytes, g_KeyPairs[senderKeyPairIndex]))
;
if (mBlockchain->addGradidoTransaction(builder.build(), nullptr, createdAt + chrono::seconds{45})) {
auto lastTransaction = mBlockchain->findOne(Filter::LAST_TRANSACTION)->getConfirmedTransaction();
auto accountIt = mKeyPairIndexAccountMap.find(senderKeyPairIndex);
accountIt->second.balance = lastTransaction->getAccountBalance();
accountIt->second.balanceDate = lastTransaction->getConfirmedAt();
return true;
}
return false;
}

void InMemoryTest::logBlockchain()
{
auto transactions = dynamic_cast<InMemory*>(mBlockchain.get())->getSortedTransactions();
Expand Down Expand Up @@ -332,3 +370,27 @@ TEST_F(InMemoryTest, InvalidCreationTransactions)
EXPECT_EQ(accountIt->second.balance, GradidoUnit(0.0));
}

TEST_F(InMemoryTest, ValidTransferTransaction)
{
ASSERT_NO_THROW(createRegisterAddress(3));
ASSERT_NO_THROW(createRegisterAddress(5));
auto createdAt = generateNewCreatedAt();
auto targetDate = getPreviousNMonth2(createdAt, 1);
try {
ASSERT_TRUE(createGradidoCreation(6, 4, 1000.0, createdAt, targetDate));
} catch(GradidoBlockchainException& ex) {
logBlockchain();
LOG_F(ERROR, ex.getFullString().data());
}
auto accountIt = mKeyPairIndexAccountMap.find(6);
EXPECT_EQ(accountIt->second.balance, GradidoUnit(1000.0));
EXPECT_GT(accountIt->second.balanceDate, createdAt);

try {
ASSERT_TRUE(createGradidoTransfer(6, 4, 500.10, generateNewCreatedAt()));
} catch(GradidoBlockchainException& ex) {
logBlockchain();
LOG_F(ERROR, ex.getFullString().data());
}
}

6 changes: 6 additions & 0 deletions test/blockchain/InMemoryTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ class InMemoryTest : public ::testing::Test
Timepoint createdAt,
Timepoint targetDate
);
bool createGradidoTransfer(
int senderKeyPairIndex,
int recipientKeyPairIndex,
GradidoUnit amount,
Timepoint createdAt
);

void logBlockchain();

Expand Down

0 comments on commit fa8c4eb

Please sign in to comment.