forked from rustyrussell/pettycoin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
inputhash.c
116 lines (98 loc) · 2.73 KB
/
inputhash.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include "hash_tx.h"
#include "inputhash.h"
#include "tx.h"
#include <ccan/hash/hash.h>
#include <ccan/structeq/structeq.h>
const struct inputhash_key *inputhash_keyof(const struct inputhash_elem *elem)
{
return &elem->output;
}
size_t inputhash_hashfn(const struct inputhash_key *key)
{
return hash_any(&key->tx, sizeof(key->tx), key->output_num);
}
bool inputhash_eq(const struct inputhash_elem *elem,
const struct inputhash_key *output)
{
return output->output_num == elem->output.output_num
&& structeq(&output->tx, &elem->output.tx);
}
static struct inputhash_elem *inputhash_i(struct htable *ht,
const struct inputhash_key *key,
struct inputhash_elem *te,
struct inputhash_iter *i,
size_t h)
{
while (te) {
if (inputhash_eq(te, key))
break;
te = htable_nextval(ht, &i->i, h);
}
return te;
}
struct inputhash_elem *inputhash_firstval(struct inputhash *inputhash,
const struct protocol_tx_id *tx,
u16 output_num,
struct inputhash_iter *i)
{
struct inputhash_key key;
size_t h;
key.tx = *tx;
key.output_num = output_num;
h = inputhash_hashfn(&key);
return inputhash_i(&inputhash->raw, &key,
htable_firstval(&inputhash->raw, &i->i, h),
i, h);
}
struct inputhash_elem *inputhash_nextval(struct inputhash *inputhash,
const struct protocol_tx_id *tx,
u16 output_num,
struct inputhash_iter *i)
{
struct inputhash_key key;
size_t h;
key.tx = *tx;
key.output_num = output_num;
h = inputhash_hashfn(&key);
return inputhash_i(&inputhash->raw, &key,
htable_nextval(&inputhash->raw, &i->i, h),
i, h);
}
void inputhash_add_tx(struct state *state,
struct inputhash *inputhash, const union protocol_tx *tx)
{
unsigned int i;
for (i = 0; i < num_inputs(tx); i++) {
struct inputhash_elem *ie;
const struct protocol_input *inp = tx_input(tx, i);
/* We allocate off state: we free up manually when
* all txs are removed from txhash */
ie = tal(state, struct inputhash_elem);
ie->output.tx = inp->input;
ie->output.output_num = le16_to_cpu(inp->output);
hash_tx(tx, &ie->used_by);
inputhash_add(inputhash, ie);
}
}
void inputhash_del_tx(struct inputhash *inputhash, const union protocol_tx *tx)
{
unsigned int i;
struct inputhash_elem *ie;
struct inputhash_iter it;
struct protocol_tx_id sha;
hash_tx(tx, &sha);
for (i = 0; i < num_inputs(tx); i++) {
const struct protocol_input *inp = tx_input(tx, i);
for (ie = inputhash_firstval(inputhash, &inp->input,
le16_to_cpu(inp->output), &it);
ie;
ie = inputhash_nextval(inputhash, &inp->input,
le16_to_cpu(inp->output), &it)) {
if (structeq(&ie->used_by, &sha)) {
htable_delval(&inputhash->raw, &it.i);
tal_free(ie);
break;
}
}
}
}