 
 block_t block;
 
-uint8_t target[HASH_SIZE];
-uint8_t current_hash[HASH_SIZE];
-uint8_t best_hash[HASH_SIZE] = {
+
+typedef struct {
+	uint8_t target[HASH_SIZE];
+	uint8_t current_hash[HASH_SIZE];
+	uint8_t best_hash[HASH_SIZE];
+	unsigned long start_time;
+	unsigned long cumulative_time;
+	uint32_t start_nonce;
+	boolean valid;
+	boolean mined;
+	boolean paused;
+} status_t;
+
+status_t status;
+
+uint8_t const max_hash[] = {
 	0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
 
-boolean valid = false;
-boolean mined = false;
-boolean paused = true;
-
-unsigned long start_time;
-unsigned long cumulative_time;
-uint32_t start_nonce;
+// M02000000da388d7496041fc6715f6fb06d93c49145afb6c25d872ebd0500000000000000425f3c31f49ce7dece098cc6236fc0c9fb099d4e73609d48d7ff42313468aa081c48a2524212061929e06286
+uint8_t test_block[] = {
+	1,0,0,0,234,141,253,92,14,35,8,200,179,166,115,97,93,250,242,143,169,3,156,
+	88,73,250,88,75,5,15,0,0,0,0,0,0,34,89,134,254,85,127,253,145,191,7,250,55,
+	82,184,161,249,5,88,122,137,30,126,220,11,228,65,119,50,21,45,140,229,12,234,
+	249,77,133,33,19,26,112,140,77,210
+};
 
 
 void setup() {
 	initialize_wireless_network();
 	connect_to_server();
+	status.paused = true;
 }
 
 
 void loop() {
 	do_server_command();
-	if (valid && !paused && !mined) {
-		do_hash(&block, current_hash);
-		int compare = memcmp(current_hash, target, HASH_SIZE);
+	if (status.valid && !status.paused && !status.mined) {
+		do_hash(&block, status.current_hash);
+		int compare = memcmp(status.current_hash, status.target, HASH_SIZE);
 		if (compare <= 0) {
-			mined = true;
-			paused = true;
-			cumulative_time += millis() - start_time;
+			status.mined = true;
+			status.paused = true;
+			status.cumulative_time += millis() - status.start_time;
 			for (int i = 0; i < HASH_SIZE; i++) {
-				best_hash[i] = current_hash[i];
+				status.best_hash[i] = status.current_hash[i];
 			}
-			print_result();
+			print_status();
 		} else {
-			int compare2 = memcmp(current_hash, best_hash, HASH_SIZE);
+			int compare2 = memcmp(status.current_hash, status.best_hash, HASH_SIZE);
 			if (compare2 <= 0) {
 				for (int i = 0; i < HASH_SIZE; i++) {
-					best_hash[i] = current_hash[i];
+					status.best_hash[i] = status.current_hash[i];
 				}
-				print_hex(best_hash, HASH_SIZE);
-				Serial.print(":");
-				Serial.println(block.header.nonce);
+				print_update();
 			}
 			block.header.nonce += 1;
 		}

		target[32 - exponent] = mantissa >> 16 & 0xFF;
		target[33 - exponent] = mantissa >> 8 & 0xFF;
		target[34 - exponent] = mantissa & 0xFF;
	} else {
		// error!
	}
}


double get_hashrate() {
	double hashes = (block.header.nonce - start_nonce) / 1000.0;
	if (paused) {
		if (cumulative_time > 0) {
			return hashes / (cumulative_time / 1000.0);
		} else {
			return 0.0;
		}
	} else {
		return hashes / ((millis() - start_time + cumulative_time) / 1000.0);
	}
}


}


void load_block(uint8_t *bytes) {
	status.valid = false;
	for (int i = 0; i < BLOCK_HEADER_SIZE; i++) {
		block.packet[i] = bytes[i];
	}
	if (block.header.version > 0) {
		status.valid = true;
	}
	status.valid = set_target(block.header.bits, status.target);
	for (int i = 0; i < HASH_SIZE; i++) {
		status.current_hash[i] = max_hash[i];
		status.best_hash[i] = max_hash[i];
	}
	status.start_time = 0;
	status.cumulative_time = 0;
	status.start_nonce = block.header.nonce;
	status.mined = false;
	status.paused = true;
}


boolean set_target(uint32_t bits, uint8_t *target) {
	for (int i = 0; i < HASH_SIZE; i++) {
		target[i] = 0;
	}
