• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

libbitcoin / libbitcoin-system / 23122982107

16 Mar 2026 12:30AM UTC coverage: 81.516% (+0.2%) from 81.295%
23122982107

push

github

web-flow
Merge pull request #1795 from evoskuil/master

Implement basic bitcoind serialization annotations/tests.

139 of 153 new or added lines in 10 files covered. (90.85%)

11149 of 13677 relevant lines covered (81.52%)

3465166.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.43
/src/chain/json/transaction.cpp
1
/**
2
 * Copyright (c) 2011-2026 libbitcoin developers (see AUTHORS)
3
 *
4
 * This file is part of libbitcoin.
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Affero General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU Affero General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Affero General Public License
17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
#include <bitcoin/system/chain/json/json.hpp>
20

21
#include <ranges>
22
#include <bitcoin/system/chain/input.hpp>
23
#include <bitcoin/system/chain/output.hpp>
24
#include <bitcoin/system/chain/transaction.hpp>
25
#include <bitcoin/system/define.hpp>
26
#include <bitcoin/system/stream/stream.hpp>
27

28
namespace libbitcoin {
29
namespace system {
30
namespace chain {
31

32
DEFINE_JSON_TO_TAG(transaction)
2✔
33
{
34
    return
2✔
35
    {
36
        value.at("version").to_number<uint32_t>(),
2✔
37
        value_to<inputs>(value.at("inputs")),
2✔
38
        value_to<outputs>(value.at("outputs")),
4✔
39
        value.at("locktime").to_number<uint32_t>()
4✔
40
    };
6✔
41
}
42

43
DEFINE_JSON_FROM_TAG(transaction)
4✔
44
{
45
    value =
16✔
46
    {
47
        // hash is computed property
48
        { "hash", encode_hash(instance.hash(false)) },
4✔
49
        { "version", instance.version() },
50
        { "inputs", value_from(*instance.inputs_ptr()) },
8✔
51
        { "outputs", value_from(*instance.outputs_ptr()) },
8✔
52
        { "locktime", instance.locktime() }
53
    };
4✔
54
}
4✔
55

56
DEFINE_JSON_TO_TAG(transaction::cptr)
×
57
{
58
    return to_shared(tag_invoke(to_tag<transaction>{}, value));
×
59
}
60

61
DEFINE_JSON_FROM_TAG(transaction::cptr)
2✔
62
{
63
    tag_invoke(from_tag{}, value, *instance);
2✔
64
}
2✔
65

66
// bitcoind
67
// ----------------------------------------------------------------------------
68

69
// There is no non-verbose tx encoding.
70
DEFINE_JSON_FROM_TAGGED(bitcoind_tag, transaction)
1✔
71
{
72
    const auto& tx = instance.value;
1✔
73
    value =
5✔
74
    {
75
        { "hex", value_from(bitcoind_embedded(tx)) },
1✔
76
        { "txid", encode_hash(tx.hash(false)) },
2✔
77
        { "hash", encode_hash(tx.hash(true)) },
2✔
78
        { "size", tx.serialized_size(false) },
79
        { "vsize", tx.virtual_size() },
80
        { "weight", tx.weight() },
81
        { "version", tx.version() },
82
        { "locktime", tx.locktime() },
83
        { "vin", value_from(bitcoind(*tx.inputs_ptr())) },
2✔
84
        { "vout", value_from(bitcoind(*tx.outputs_ptr())) }
2✔
85

86
        ////{ "in_active_chain", false },
87
        ////{ "blockhash", "" },
88
        ////{ "confirmations", 0 },
89
        ////{ "blocktime", 0 },
90
        ////{ "time", 0 }
91
    };
1✔
92
}
1✔
93

94
DEFINE_JSON_FROM_TAGGED(bitcoind_hashed_tag, transaction)
1✔
95
{
96
    const auto& tx = instance.value;
1✔
97
    value = value_from(encode_hash(tx.hash(false)));
1✔
98
}
1✔
99

100
DEFINE_JSON_FROM_TAGGED(bitcoind_embedded_tag, transaction)
2✔
101
{
102
    const auto& tx = instance.value;
2✔
103

104
    // Streaming hex encode is a material performance optimization.
105
    ////const auto hash = encode_base16(tx.hash(false));
106
    std::string hash(two * tx.serialized_size(true), '\0');
2✔
107
    stream::out::fast sink{ hash };
2✔
108
    write::base16::fast writer{ sink };
2✔
109
    tx.to_data(writer, true);
2✔
110
    BC_ASSERT(writer);
2✔
111

112
    value = value_from(hash);
2✔
113
}
4✔
114

NEW
115
DEFINE_JSON_FROM_TAGGED(bitcoind_verbose_tag, transaction)
×
116
{
NEW
117
    const auto& tx = instance.value;
×
NEW
118
    value = value_from(tx);
×
NEW
119
}
×
120

121
// The tag wrapper masks the vector, so these must be explicit.
122
// ----------------------------------------------------------------------------
123

124
BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
125

126
DEFINE_JSON_FROM_TAGGED(bitcoind_tag, transaction_cptrs)
1✔
127
{
128
    const auto& txs = instance.value;
1✔
129
    value = boost::json::array(txs.size());
1✔
130
    std::ranges::transform(txs, value.as_array().begin(),
2✔
131
        [](const chain::transaction::cptr& tx) NOEXCEPT
1✔
132
        {
133
            return value_from(bitcoind(*tx));
1✔
134
        });
135
}
1✔
136

137
DEFINE_JSON_FROM_TAGGED(bitcoind_hashed_tag, transaction_cptrs)
1✔
138
{
139
    const auto& txs = instance.value;
1✔
140
    value = boost::json::array(txs.size());
1✔
141
    std::ranges::transform(txs, value.as_array().begin(),
2✔
142
        [](const chain::transaction::cptr& tx) NOEXCEPT
1✔
143
        {
144
            return value_from(bitcoind_hashed(*tx));
1✔
145
        });
146
}
1✔
147

148
DEFINE_JSON_FROM_TAGGED(bitcoind_embedded_tag, transaction_cptrs)
1✔
149
{
150
    const auto& txs = instance.value;
1✔
151
    value = boost::json::array(txs.size());
1✔
152
    std::ranges::transform(txs, value.as_array().begin(),
2✔
153
        [](const chain::transaction::cptr& tx) NOEXCEPT
1✔
154
        {
155
            return value_from(bitcoind_embedded(*tx));
1✔
156
        });
157
}
1✔
158

NEW
159
DEFINE_JSON_FROM_TAGGED(bitcoind_verbose_tag, transaction_cptrs)
×
160
{
NEW
161
    const auto& txs = instance.value;
×
NEW
162
    value = boost::json::array(txs.size());
×
NEW
163
    std::ranges::transform(txs, value.as_array().begin(),
×
NEW
164
        [](const chain::transaction::cptr& tx) NOEXCEPT
×
165
        {
NEW
166
            return value_from(*tx);
×
167
        });
NEW
168
}
×
169

170
BC_POP_WARNING()
171

172
} // namespace chain
173
} // namespace system
174
} // namespace libbitcoin
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc