/* * This file is part of the Flowee project * Copyright (C) 2021-2023 Tom Zander * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "TestProtoBuf.h" #include "fusion.pb.h" #include "streaming/BufferPools.h" #include #include #include #include #include #include template Streaming::ConstBuffer store(T object) { std::string data; object->SerializeToString(&data); auto &pool = Streaming::pool(data.size()); memcpy(pool.begin(), data.c_str(), data.size()); return pool.commit(data.size()); } TestProtoBuf::TestProtoBuf() : testString("testApp1"), hash(uint256S("0x1234567890aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")) { } void TestProtoBuf::testParser() { auto oc = new fusion::ClientHello; oc->set_version(testString); auto stored = store(oc); Streaming::ProtoParser pp(stored); QCOMPARE(pp.next(), Streaming::FoundTag); QCOMPARE(pp.tag(), 1); QCOMPARE(pp.isByteArray(), true); QCOMPARE(pp.dataLength(), testString.size()); QCOMPARE(pp.stringData(), testString); QCOMPARE(pp.next(), Streaming::EndOfDocument); oc->set_genesis_hash(hash.begin(), 32); stored = store(oc); Streaming::ProtoParser pp2(stored); QCOMPARE(pp2.next(), Streaming::FoundTag); QCOMPARE(pp2.tag(), 1); QCOMPARE(pp2.isByteArray(), true); QCOMPARE(pp2.dataLength(), testString.size()); QCOMPARE(pp2.stringData(), testString); QCOMPARE(pp2.next(), Streaming::FoundTag); QCOMPARE(pp2.tag(), 2); QCOMPARE(pp2.isByteArray(), true); QCOMPARE(pp2.dataLength(), 32); QCOMPARE(pp2.uint256Data(), hash); QCOMPARE(pp2.next(), Streaming::EndOfDocument); auto ic = new fusion::InputComponent; ic->set_prev_txid(hash.begin(), 32); ic->set_prev_index(130); ic->set_pubkey(testString); ic->set_amount(50000); stored = store(ic); Streaming::ProtoParser pp3(stored); QCOMPARE(pp3.next(), Streaming::FoundTag); QCOMPARE(pp3.tag(), 1); QCOMPARE(pp3.isByteArray(), true); QCOMPARE(pp3.dataLength(), 32); QCOMPARE(pp3.uint256Data(), hash); // defined as an uint32 in the proto file. // this is stored as a VarInt QCOMPARE(pp3.next(), Streaming::FoundTag); QCOMPARE(pp3.tag(), 2); QCOMPARE(pp3.isByteArray(), false); QCOMPARE(pp3.isLong(), true); QCOMPARE(pp3.isInt(), true); QCOMPARE(pp3.intData(), 130); QCOMPARE(pp3.next(), Streaming::FoundTag); QCOMPARE(pp3.tag(), 3); QCOMPARE(pp3.isByteArray(), true); QCOMPARE(pp3.dataLength(), testString.size()); QCOMPARE(pp3.stringData(), testString); // defined as an uint64 in the proto file. // this is stored as a VarInt QCOMPARE(pp3.next(), Streaming::FoundTag); QCOMPARE(pp3.tag(), 4); QCOMPARE(pp3.isByteArray(), false); QCOMPARE(pp3.isLong(), true); QCOMPARE(pp3.isInt(), true); QCOMPARE(pp3.intData(), 50000); QCOMPARE(pp3.next(), Streaming::EndOfDocument); // test varint with different numbers std::array tests = { 1000000, 123452156, 91713727327389, 200, 2200000000 }; for (auto i = 0; i < tests.size(); ++i) { ic->set_amount(tests[i]); stored = store(ic); Streaming::ProtoParser parser(stored); while (parser.next() == Streaming::FoundTag) { if (parser.tag() == 4) { QCOMPARE(parser.longData(), tests[i]); } } } } void TestProtoBuf::testBuilder() { Streaming::ProtoBuilder builder(Streaming::pool(100)); builder.add(1, testString); builder.add(2, hash); auto stored = builder.buffer(); auto oc = new fusion::ClientHello; QVERIFY(oc->ParseFromArray(stored.begin(), stored.size())); QCOMPARE(oc->version(), testString); QCOMPARE(oc->genesis_hash(), std::string(hash.begin(), hash.end())); } void TestProtoBuf::testBuilder2() { Streaming::ProtoBuilder builder(Streaming::pool(100)); builder.add(1, hash); builder.add(2, 300); builder.add(3, testString); builder.add(4, 50000); auto stored = builder.buffer(); auto ic = new fusion::InputComponent; QVERIFY(ic->ParseFromArray(stored.begin(), stored.size())); uint256 prevTxId(ic->prev_txid().c_str()); QCOMPARE(prevTxId, hash); QCOMPARE(ic->prev_index(), 300); QCOMPARE(ic->pubkey(), testString); QCOMPARE(ic->amount(), 50000); } void TestProtoBuf::testNestedBuilder() { Streaming::ProtoBuilder builder(Streaming::pool(100)); builder.add(1, 123456789); builder.add(1, 126666600); auto nested = builder.addNestedMessage(2); nested->add(1, testString); nested->add(2, 5); nested = nullptr; auto stored = builder.buffer(); auto jp = new fusion::JoinPools; QVERIFY(jp->ParseFromArray(stored.begin(), stored.size())); QCOMPARE(jp->tiers_size(), 2); QCOMPARE(jp->tiers(0), 123456789); QCOMPARE(jp->tiers(1), 126666600); QCOMPARE(jp->tags_size(), 1); auto t = jp->tags(0); QCOMPARE(t.id(), testString); QCOMPARE(t.limit(), 5); } void TestProtoBuf::testNestedParser() { auto jp = new fusion::JoinPools; jp->add_tiers(50); jp->add_tiers(800); auto *tag = jp->add_tags(); tag->set_id(testString); tag->set_limit(601); auto stored = store(jp); Streaming::ProtoParser parser(stored); QCOMPARE(parser.next(), Streaming::FoundTag); QCOMPARE(parser.tag(), 1); QCOMPARE(parser.intData(), 50); QCOMPARE(parser.next(), Streaming::FoundTag); QCOMPARE(parser.tag(), 1); QCOMPARE(parser.intData(), 800); QCOMPARE(parser.next(), Streaming::FoundTag); QCOMPARE(parser.tag(), 2); QCOMPARE(parser.isByteArray(), true); QCOMPARE(parser.depth(), 1); parser.enterData(); QCOMPARE(parser.depth(), 2); QCOMPARE(parser.next(), Streaming::FoundTag); QCOMPARE(parser.tag(), 1); QCOMPARE(parser.isByteArray(), true); QCOMPARE(parser.dataLength(), testString.size()); QCOMPARE(parser.stringData(), testString); QCOMPARE(parser.next(), Streaming::FoundTag); QCOMPARE(parser.tag(), 2); QCOMPARE(parser.isInt(), true); QCOMPARE(parser.intData(), 601); QCOMPARE(parser.next(), Streaming::EndOfDocument); QCOMPARE(parser.depth(), 2); parser.closeData(); QCOMPARE(parser.depth(), 1); QCOMPARE(parser.next(), Streaming::EndOfDocument); // repeated calls have no effect. parser.closeData(); QCOMPARE(parser.depth(), 1); QCOMPARE(parser.next(), Streaming::EndOfDocument); } QTEST_MAIN(TestProtoBuf)