From 4fa3a3416e5e58d3c769cfa7298891fafd0e5a76 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 11 Aug 2016 11:40:29 -0400 Subject: [PATCH] Add basic versionbits (BIP9) gbt rules logic A "rules" array is passed into the template request, indicating the understood softfork deployments. In the response, a "rules" array is also passed back, indicating the rules that are active. If this rule begins with a "!", it means that blocks cannot be successfully created without understanding the rule. --- src/bitcoin.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/bitcoin.c b/src/bitcoin.c index 016a543f..63fb97d9 100644 --- a/src/bitcoin.c +++ b/src/bitcoin.c @@ -17,6 +17,17 @@ static const char *b58chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; +static char* understood_rules[] = {}; +static bool check_required_rule(const char* rule) +{ + unsigned int i; + for(i = 0; i < sizeof(understood_rules) / sizeof(understood_rules[0]); i++) { + if(strcmp(understood_rules[i], rule) == 0) + return true; + } + return false; +} + /* Take a bitcoin address and do some sanity checks on it, then send it to * bitcoind to see if it's a valid address */ bool validate_address(connsock_t *cs, const char *address) @@ -86,16 +97,18 @@ static const char *gbt_req = "{\"method\": \"getblocktemplate\", \"params\": [{\ * required to assemble a mining template, storing it in a gbtbase_t structure */ bool gen_gbtbase(connsock_t *cs, gbtbase_t *gbt) { - json_t *txn_array, *coinbase_aux, *res_val, *val; + json_t *txn_array, *rules_array, *coinbase_aux, *res_val, *val; const char *previousblockhash; char hash_swap[32], tmp[32]; uint64_t coinbasevalue; const char *target; const char *flags; const char *bits; + const char *rule; int version; int curtime; int height; + int i; bool ret = false; val = json_rpc_call(cs, gbt_req); @@ -109,6 +122,18 @@ bool gen_gbtbase(connsock_t *cs, gbtbase_t *gbt) goto out; } + rules_array = json_object_get(res_val, "rules"); + if(rules_array) { + int rule_count = json_array_size(rules_array); + for(i = 0; i < rule_count; i++) { + rule = json_string_value(json_array_get(rules_array, i)); + if(rule && *rule++ == '!' && !check_required_rule(rule)) { + LOGERR("Required rule not understood: %s", rule); + goto out; + } + } + } + previousblockhash = json_string_value(json_object_get(res_val, "previousblockhash")); target = json_string_value(json_object_get(res_val, "target")); txn_array = json_object_get(res_val, "transactions"); @@ -165,6 +190,9 @@ bool gen_gbtbase(connsock_t *cs, gbtbase_t *gbt) json_object_set_new_nocheck(gbt->json, "flags", json_string_nocheck(gbt->flags)); json_object_set_new_nocheck(gbt->json, "transactions", json_deep_copy(txn_array)); + + json_object_set_new_nocheck(gbt->json, "rules", json_deep_copy(rules_array)); + ret = true; out: