File: example.c

package info (click to toggle)
libblkmaker 0.5.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 176 kB
  • ctags: 165
  • sloc: ansic: 1,306; makefile: 67; sh: 7
file content (130 lines) | stat: -rw-r--r-- 3,275 bytes parent folder | download
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 * Copyright 2012 Luke Dashjr
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the standard MIT license.  See COPYING for more details.
 */

#include <assert.h>
#include <inttypes.h>
#include <stdint.h>

#include <arpa/inet.h>

#include <gcrypt.h>
#include <libbase58.h>

#include <blkmaker.h>
#include <blkmaker_jansson.h>

#include "private.h"
#include "testinput.c"

void testb58() {
	int rv;
	const char *iaddr = "11Baf75Ferj6A7AoN565gCQj9kGWbDMHfN9";
	const char *addr = &iaddr[1];
	const size_t addrlen = strlen(addr);
	size_t actuallen;
	char bufx[26] = {'\xff'};
	char *buf = &bufx[1];
	actuallen = 25;
	if (!b58tobin(buf, &actuallen, addr, addrlen))
		exit(1);
	if (bufx[0] != '\xff')
		exit(2);
	char cbuf[51];
	_blkmk_bin2hex(cbuf, buf, 25);
	printf("Base58 raw data: %s\n", cbuf);
	assert((rv = b58check(buf, 25, addr, addrlen)) == 0);
	printf("Base58 check: %d\n", rv);
	assert((rv = b58check(buf, 25, &addr[1], addrlen)) < 0);
	printf("Base58 check (invalid/    unpadded): %d\n", rv);
	assert((rv = b58check(buf, 25, iaddr, addrlen + 1)) < 0);
	printf("Base58 check (invalid/extra padded): %d\n", rv);
}

static
void send_json(json_t *req) {
	char *s = json_dumps(req, JSON_INDENT(2));
	puts(s);
	free(s);
}

static
bool my_sha256(void *digest, const void *buffer, size_t length) {
	gcry_md_hash_buffer(GCRY_MD_SHA256, digest, buffer, length);
	return true;
}

int main(int argc, char**argv) {
	blktemplate_t *tmpl;
	json_t *req;
	json_error_t jsone;
	const char *err;
	
	b58_sha256_impl = my_sha256;
	blkmk_sha256_impl = my_sha256;
	
	testb58();
	
	tmpl = blktmpl_create();
	assert(tmpl);
	req = blktmpl_request_jansson(blktmpl_addcaps(tmpl), NULL);
	assert(req);
	
	// send req to server and parse response into req
	send_json(req);
	json_decref(req);
	if (argc == 2)
		req = json_loadf(stdin, JSON_DISABLE_EOF_CHECK, &jsone);
	else
	{
		req = json_loads(blkmaker_test_input, 0, &jsone);
		send_json(req);
	}
	assert(req);
	
	err = blktmpl_add_jansson(tmpl, req, time(NULL));
	json_decref(req);
	if (err)
	{
		fprintf(stderr, "Error adding block template: %s", err);
		assert(0 && "Error adding block template");
	}
	while (blkmk_time_left(tmpl, time(NULL)) && blkmk_work_left(tmpl))
	{
		unsigned char data[80], hash[32];
		size_t datasz;
		unsigned int dataid;
		uint32_t nonce;
		
		datasz = blkmk_get_data(tmpl, data, sizeof(data), time(NULL), NULL, &dataid);
		assert(datasz >= 76 && datasz <= sizeof(data));
		
		// mine the right nonce
		// this is iterating in native order, even though SHA256 is big endian, because we don't implement noncerange
		// however, the nonce is always interpreted as big endian, so we need to convert it as if it were big endian
		for (nonce = 0; nonce < 0xffffffff; ++nonce)
		{
			*(uint32_t*)(&data[76]) = nonce;
			assert(my_sha256(hash, data, 80));
			assert(my_sha256(hash, hash, 32));
			if (!*(uint32_t*)(&hash[28]))
				break;
			if (!(nonce % 0x1000))
			{
				printf("0x%8" PRIx32 " hashes done...\r", nonce);
				fflush(stdout);
			}
		}
		printf("Found nonce: 0x%8" PRIx32 " \n", nonce);
		nonce = ntohl(nonce);
		
		req = blkmk_submit_jansson(tmpl, data, dataid, nonce);
		assert(req);
		// send req to server
		send_json(req);
	}
	blktmpl_free(tmpl);
}