/** * Clear the given surface to the specified value. * No masking, no scissor (clear entire buffer). */ static void brw_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, double depth, unsigned stencil) { struct brw_context *brw = brw_context( pipe ); int i; if (buffers & PIPE_CLEAR_COLOR) { for (i = 0; i < brw->curr.fb.nr_cbufs; i++) { color_clear( brw, brw_surface(brw->curr.fb.cbufs[i]), rgba ); } } if (buffers & PIPE_CLEAR_DEPTHSTENCIL) { if (brw->curr.fb.zsbuf) { zstencil_clear( brw, brw_surface(brw->curr.fb.zsbuf), buffers & PIPE_CLEAR_DEPTHSTENCIL, depth, stencil ); } } }
/* XXX should respect region */ static void brw_clear_render_target(struct pipe_context *pipe, struct pipe_surface *dst, const float *rgba, unsigned dstx, unsigned dsty, unsigned width, unsigned height) { struct brw_context *brw = brw_context( pipe ); color_clear( brw, brw_surface(dst), rgba ); }
/* * Print a message. */ static void print_msg(struct in6_addr addr, const char *msg) { char name[INET6_ADDRSTRLEN+1]; inet_ntop(AF_INET6, &addr, name, sizeof(name)); mutex_lock(&lock); if (!prev_msg) putchar('\n'); color_warning(); printf("warning"); color_clear(); printf(": [%s] %s\n", name, msg); prev_msg = true; mutex_unlock(&lock); }
/* * Print a block. */ static void print_block(struct PN *node, const uint8_t *block, size_t len) { const size_t hdrlen = 80; jmp_buf env; struct buf buf0 = {block + hdrlen, 0, len - hdrlen, &env}; struct buf *buf = &buf0; if (len <= hdrlen || setjmp(env)) { parse_error: fprintf(stderr, "error: unable to parse block\n"); return; } size_t num_tx = pop_varint(buf); if (num_tx >= MAX_BLOCK_TXS) goto parse_error; hash256_t hashes[num_tx]; for (size_t i = 0; i < num_tx; i++) { size_t start = buf->ptr; if (!parse_tx(buf, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) goto parse_error; size_t end = buf->ptr; PN_sha256d(buf->data + start, end - start, hashes + i); } mutex_lock(&lock); num_blocks++; putchar('\n'); printf(" " "+----------------------------------------------------------------+\n"); for (size_t i = 0; i < num_tx; i++) { printf(" |"); color_hash(); for (size_t j = 0; j < 32; j++) printf("%.2x", hashes[i].i8[32 - j - 1]); color_clear(); printf("|\n"); } printf(" " "+----------------------------------------------------------------+\n"); if (option_verbose) { printf("NODE : height=%u in=%u out=%u sent=%.2gMB recv=%.2gMB\n", PN_get_info(node, PN_HEIGHT), PN_get_info(node, PN_NUM_IN_PEERS), PN_get_info(node, PN_NUM_OUT_PEERS), (double)PN_get_info(node, PN_NUM_SEND_BYTES) / 1000000.0, (double)PN_get_info(node, PN_NUM_RECV_BYTES) / 1000000.0); printf("BLOCK : hash="); hash256_t hash; PN_sha256d(block, 80, &hash); for (size_t i = 0; i < sizeof(hash); i++) printf("%.2x", hash.i8[32 - i - 1]); printf("\n size=%uB #tx=%u\n", (unsigned)len, (unsigned)num_tx); printf("TOTALS: #tx=%u #block=%u size=%uB val=%gBTC\n", (unsigned)num_tx, (unsigned)num_blocks, (unsigned)num_tx_bytes, GET_BTC(total_val)); } prev_msg = false; mutex_unlock(&lock); }
/* * Print a transaction. */ static void print_tx(struct PN *node, const uint8_t *tx, size_t len) { uint8_t *ins[MAX_INPUTS]; size_t inlens[MAX_INPUTS]; uint8_t *outs[MAX_OUTPUTS]; size_t outlens[MAX_OUTPUTS]; uint64_t outvals[MAX_OUTPUTS]; jmp_buf env; struct buf buf0 = {tx, 0, len, &env}; struct buf *buf = &buf0; if (setjmp(env)) { parse_error: fprintf(stderr, "error: unable to parse transaction\n"); return; } size_t num_ins, num_outs; if (!parse_tx(buf, ins, inlens, &num_ins, outs, outlens, outvals, &num_outs)) goto parse_error; // Formatting constraints: size_t lines = MAX(num_ins, num_outs); size_t in_d = lines - num_ins; size_t out_d = lines - num_outs; size_t in_s = 0 + in_d / 2; size_t in_e = lines - (in_d + 1) / 2; size_t out_s = 0 + out_d / 2; size_t out_e = lines - (out_d + 1) / 2; size_t mid = (in_s + in_e) / 2; time_t t = time(NULL); mutex_lock(&lock); putchar('\n'); num_tx++; num_tx_bytes += len; for (size_t i = 0; i < lines; i++) { if (i >= in_s && i < in_e) { size_t idx = i - in_s; uint8_t pub_key[65]; uint8_t script[520]; size_t script_len; char addr[35]; addr[0] = '\0'; if (script_is_p2pkh_input(ins[idx], inlens[idx], pub_key)) { size_t pub_key_len = (pub_key[0] == 0x04? 65: 33); make_input_addr(pub_key, pub_key_len, 0x00, addr); } else if (script_is_p2sh_input(ins[idx], inlens[idx], script, &script_len)) make_input_addr(script, script_len, 0x05, addr); if (addr[0] != '\0') { color_input(); printf("%s", addr); color_clear(); size_t len = strlen(addr); for (size_t j = 0; j < 34 - len; j++) putchar(' '); } else printf("[UNKNOWN] "); } else { for (size_t i = 0; i < 34; i++) putchar(' '); } putchar(' '); if (i >= out_s && i < out_e) { size_t idx = i - out_s; uint8_t hash160[20]; char addr[35]; uint8_t data[80]; size_t dlen; bool is_data = false; addr[0] = '\0'; if (script_is_p2pkh_output(outs[idx], outlens[idx], hash160)) make_output_addr(hash160, 0x00, addr); else if (script_is_p2sh_output(outs[idx], outlens[idx], hash160)) make_output_addr(hash160, 0x05, addr); else if (script_is_data_output(outs[idx], outlens[idx], data, &dlen)) is_data = true; if (addr[0] != '\0') { color_output(); printf("%s", addr); color_clear(); size_t len = strlen(addr); for (size_t j = 0; j < 34 - len; j++) putchar(' '); } else if (is_data) { color_output(); printf("[DATA] \""); size_t space = 26, j; for (j = 0; j < dlen && j < 22; j++) { if (isprint(data[j])) putchar(data[j]); else putchar('?'); space--; } if (j < dlen) { printf("..."); space -= 3; } putchar('\"'); space--; for (j = 0; j < space; j++) putchar(' '); color_clear(); } else printf("[UNKNOWN] "); // The following is complicated way to ensure the number fits: color_value(); double val = GET_BTC(outvals[idx]); double btc_val = (double)(unsigned)(val); char buf[32]; size_t len = snprintf(buf, sizeof(buf)-1, "%u", (unsigned)btc_val); if (len > 8) { printf("UNKNOWN\n"); color_clear(); continue; } printf(" %s", buf); double mant = val - btc_val; if (mant == 0.0) { color_clear(); putchar('\n'); continue; } size_t prec = 8 - len; switch (prec) { case 1: len = snprintf(buf, sizeof(buf)-1, "%.1f", mant); break; case 2: len = snprintf(buf, sizeof(buf)-1, "%.2f", mant); break; case 3: len = snprintf(buf, sizeof(buf)-1, "%.3f", mant); break; case 4: len = snprintf(buf, sizeof(buf)-1, "%.4f", mant); break; case 5: len = snprintf(buf, sizeof(buf)-1, "%.5f", mant); break; case 6: len = snprintf(buf, sizeof(buf)-1, "%.6f", mant); break; case 7: len = snprintf(buf, sizeof(buf)-1, "%.7f", mant); break; case 8: len = snprintf(buf, sizeof(buf)-1, "%.8f", mant); break; default: buf[1] = '\0'; len = 0; break; } while (len >= 2 && buf[len-1] == '0') { buf[len-1] = '\0'; len--; } printf("%s", buf+1); color_clear(); } putchar('\n'); } if (option_verbose) { printf("NODE : height=%u in=%u out=%u sent=%.2gMB recv=%.2gMB\n", PN_get_info(node, PN_HEIGHT), PN_get_info(node, PN_NUM_IN_PEERS), PN_get_info(node, PN_NUM_OUT_PEERS), (double)PN_get_info(node, PN_NUM_SEND_BYTES) / 1000000.0, (double)PN_get_info(node, PN_NUM_RECV_BYTES) / 1000000.0); printf("TX : hash="); hash256_t hash; PN_sha256d(tx, len, &hash); for (size_t i = 0; i < sizeof(hash); i++) printf("%.2x", hash.i8[32 - i - 1]); uint64_t tx_val = 0; for (size_t i = 0; i < num_outs; i++) tx_val += outvals[i]; total_val += tx_val; printf("\n size=%uB inputs=%u outputs=%u val=%gBTC\n", (unsigned)len, (unsigned)num_ins, (unsigned)num_outs, GET_BTC(tx_val)); printf("TOTALS: #tx=%u #block=%u size=%uB val=%gBTC\n", (unsigned)num_tx, (unsigned)num_blocks, (unsigned)num_tx_bytes, GET_BTC(total_val)); double vps, sps, txps; get_rate_info(t, tx_val, len, &vps, &sps, &txps); printf("RATES : tx/s=%.3g bytes/s=%g BTC/s=%g\n", txps, sps, GET_BTC(vps)); } prev_msg = false; mutex_unlock(&lock); }