diff --git a/CHANGES.TXT b/CHANGES.TXT index 87c88c12..3d4d4545 100644 --- a/CHANGES.TXT +++ b/CHANGES.TXT @@ -5,6 +5,22 @@ */ Patch Level 37 (Mochimo v2.4.1) + + Changed PATCHLEVEL to 37 in mochimo.c and minertest.c + Changed VERSIONSTR to "37" in mochimo.c and minertest.c + Fixed previous hash check in checkproof() in proof.c + Added byte Insyncup; /* non-zero when syncup() runs */ to data.c + Added Insyncup to syncup() in syncup.c + Added addrlen to le_find() in ledger.c + Added Tagidx[] to tag.c + Changed tag_find() in tag.c, txclean.c, and mtxval.c + Added tag_free() to tag.c, update.c + Changed pval.c server.c, and config.h to allow 0xff pseudo-blocks + Removed bigwait from server.c + Added proper time_t vtime for vstart.lck check in server.c + Added Insyncup to update() in update.c to help plog()'s + Added char *solvestr to update() to reckon pushed, solved, and updated blocks. + Simplified parameter logic in tag_valid() and calls from bval and txval.c. Added Syncup Function, Removing Contention made mochimo/bin/d/split modified bx.c to indicate tags not found in MTX. diff --git a/src/bval.c b/src/bval.c index 4f96bbd7..38a9f41e 100644 --- a/src/bval.c +++ b/src/bval.c @@ -310,7 +310,7 @@ int main(int argc, char **argv) if(cmp64(src_le.balance, total) != 0) drop("bad transaction total"); if(!ismtx(&tx)) { - if(tag_valid(tx.src_addr, tx.chg_addr, tx.dst_addr, 0, bt.bnum) + if(tag_valid(tx.src_addr, tx.chg_addr, tx.dst_addr, bt.bnum) != VEOK) drop("tag not valid"); } else { if(mtx_val((MTX *) &tx, Mfee) != 0) drop("bad mtx_val()"); diff --git a/src/bx.c b/src/bx.c index 5bb55c4b..f929c048 100644 --- a/src/bx.c +++ b/src/bx.c @@ -432,15 +432,27 @@ void disp_bh(BHEADER *bh, BTRAILER *bt) /* Hex converter */ void hexcon(void) { - char buff[81]; + char buff[81], *cp; unsigned long val; + int n; for(;;) { - printf("Enter value (e.g. decimal 123, or hex 0123, p=previous): "); + printf("Enter value (e.g. 'string, or decimal 123, or hex 0123," + " p=previous):\n"); tgets(buff, 80); + if(*buff == '\'') { + printf("0x"); + for(cp = buff + 1; *cp; cp++) printf("%02x", *cp); + printf("\n"); + continue; + } if(buff[0] < '0' || buff[0] > '9') break; val = getval(buff); - printf("%lu (0x%lx) [0x%s]\n", val, val, b2hex8((byte *) &val)); + printf("%lu (0x%lx) [0x%s] ", val, val, b2hex8((byte *) &val)); + for(cp = (char *) &val, n = sizeof(val); n; n--, cp++) { + if(*cp >= ' ' && *cp < 127) printf("%c", *cp); else printf("."); + } + printf("\n"); } /* end for */ } diff --git a/src/config.h b/src/config.h index ddb26b37..34caa30f 100644 --- a/src/config.h +++ b/src/config.h @@ -87,13 +87,13 @@ /* NEWYEAR trigger */ #define NEWYEAR(bnum) (get32(bnum) >= V23TRIGGER || get32(bnum+4) != 0) -#define WATCHTIME (BRIDGE*4+1) /* Default minimum watchdog time for -w switch */ +#define WATCHTIME (BRIDGE*4+1) /* minimum watchdog time */ #define BRIDGE 949 /* Trouble time -- Edit for testing */ #define TIMES_OF_TROUBLE() (Ltime >= Bridgetime \ - && Cblocknum[0] != 0xfe \ && (get32(Cblocknum) >= V23TRIGGER \ || get32(Cblocknum+4) != 0)) -#ifndef UBANDWIDTH + +#ifndef UBANDWIDTH #define UBANDWIDTH 14300 /* Dynamic upload bandwidth -- not zero */ #endif diff --git a/src/data.c b/src/data.c index 8aca3827..673e9cee 100644 --- a/src/data.c +++ b/src/data.c @@ -72,6 +72,7 @@ word32 Coreplist[CORELISTLEN] = { /* ip's of the Core Network */ int Quorum = 4; /* Number of peers in get_eon() gang[MAXQUORUM] */ byte Ininit; /* non-zero when init() runs */ +byte Insyncup; /* non-zero when syncup() runs */ byte Safemode; /* Safe mode enable */ byte Nominer; /* Do not start miner if true -n */ word32 Watchdog; /* enable watchdog timeout -wN */ diff --git a/src/ledger.c b/src/ledger.c index f07eb565..4c443cd2 100644 --- a/src/ledger.c +++ b/src/ledger.c @@ -1,4 +1,4 @@ -/* ledger.c Search, read, and write to ledger.dat +/* ledger.c Open, close, and search ledger.dat * * Copyright (c) 2019 by Adequate Systems, LLC. All Rights Reserved. * See LICENSE.PDF **** NO WARRANTY **** @@ -55,6 +55,7 @@ void le_close(void) int le_find(byte *addr, LENTRY *le, long *position, int mode) { long cond, mid, hi, low; + size_t addrlen; if(Lefp == NULL) { Lerror = error("le_find(): use le_open() first!"); @@ -63,6 +64,7 @@ int le_find(byte *addr, LENTRY *le, long *position, int mode) low = 0; hi = Nledger - 1; + if(mode == 1) addrlen = TXADDRLEN-12; else addrlen = TXADDRLEN; while(low <= hi) { mid = (hi + low) / 2; @@ -70,11 +72,7 @@ int le_find(byte *addr, LENTRY *le, long *position, int mode) { Lerror = error("le_find(): fseek"); break; } if(fread(le, 1, sizeof(LENTRY), Lefp) != sizeof(LENTRY)) { Lerror = error("le_find(): fread"); break; } - if(mode == 1) { - cond = memcmp(addr, le->addr, TXADDRLEN-12); - } else { - cond = memcmp(addr, le->addr, TXADDRLEN); - } + cond = memcmp(addr, le->addr, addrlen); if(cond == 0) { if(position) *position = mid; return 1; /* found target addr */ diff --git a/src/makebx b/src/makebx new file mode 100755 index 00000000..c0ec5030 --- /dev/null +++ b/src/makebx @@ -0,0 +1,6 @@ +#!/bin/sh +echo Making bx... +cc -DUNIXLIKE -DLONG64 -c crypto/hash/cpu/sha256.c +cc -DUNIXLIKE -DLONG64 -c algo/trigg/trigg.c +cc -DUNIXLIKE -DLONG64 -o bx bx.c trigg.o sha256.o +rm trigg.o sha256.o diff --git a/src/minertest.c b/src/minertest.c index 606f4ae9..962d81e3 100644 --- a/src/minertest.c +++ b/src/minertest.c @@ -1,6 +1,6 @@ -#define PATCHLEVEL 36 -#define VERSIONSTR "36" /* as printable string */ +#define PATCHLEVEL 37 +#define VERSIONSTR "37" /* as printable string */ /* Include everything that we need */ #include "config.h" diff --git a/src/mochimo.c b/src/mochimo.c index e4fe08e7..7c7e491a 100644 --- a/src/mochimo.c +++ b/src/mochimo.c @@ -10,8 +10,8 @@ */ /* build sequence */ -#define PATCHLEVEL 36 -#define VERSIONSTR "36" /* as printable string */ +#define PATCHLEVEL 37 +#define VERSIONSTR "37" /* as printable string */ /* Include everything that we need */ #include "config.h" diff --git a/src/mtxval.c b/src/mtxval.c index 9e3b2da0..66831398 100644 --- a/src/mtxval.c +++ b/src/mtxval.c @@ -55,7 +55,7 @@ int mtx_val(MTX *mtx, word32 *fee) memcpy(ADDR_TAG_PTR(addr), mtx->dst[j].tag, ADDR_TAG_LEN); mtx->zeros[j] = 0; /* If dst[j] tag not found, put error code in zeros[] array. */ - if(tag_find(addr, addr, NULL) != VEOK) mtx->zeros[j] = 1; + if(tag_find(addr, NULL, NULL) != VEOK) mtx->zeros[j] = 1; } } /* end for j */ /* Check tallies... */ diff --git a/src/proof.c b/src/proof.c index ebdb2668..0a7c5f9e 100644 --- a/src/proof.c +++ b/src/proof.c @@ -63,7 +63,7 @@ int past_weight(byte *weight, word32 lownum) if(lownum >= cbnum) BAIL(1); memcpy(weight, Weight, 32); for( ; cbnum > lownum; cbnum--) { - if((cbnum & 0xff) == 0) continue; + if((cbnum & 0xff) == 0) continue; /* skip NG blocks */ if(readtf(&bts, cbnum, 1) != 1) BAIL(2); sub_weight(weight, bts.difficulty[0]); } @@ -74,7 +74,8 @@ int past_weight(byte *weight, word32 lownum) return message; } /* end past_weight() */ -#define INVALID_DIFFICULTY 256 + +#define INVALID_DIFF 256 /* Check the proof given from peer's tfile.dat in an OP_FOUND message. * Return VEOK to run syncup(), else error code to ignore peer. @@ -90,8 +91,6 @@ int checkproof(TX *tx, word32 *splitblock) static word32 v24trigger[2] = { V24TRIGGER, 0 }; byte weight[32]; - diff = INVALID_DIFFICULTY; - /* Check preconditions for proof scan: */ *splitblock = 0; /* invalid syncup() block */ if(get32(Cblocknum) < V23TRIGGER) goto allow; @@ -108,13 +107,12 @@ int checkproof(TX *tx, word32 *splitblock) count = readtf(&bts, tnum[0], 1); /* so read our tfile */ /* and compare it to theirs. */ if(count != 1 || memcmp(bt, &bts, sizeof(BTRAILER)) != 0) BAIL(1); - /* Compute our weight at their low block number. */ + /* If we get here, our weights must also match at the first trailer. */ + /* Compute our weight at their low block number less one. */ if(past_weight(weight, tnum[0] - 1) != VEOK) BAIL(2); - /* If we get here, our weights must also match at the first trailer - * and that weight is now in weight[]. - */ /* Verify peer's proof trailers in OP_FOUND TX. */ + diff = INVALID_DIFF; now = time(NULL); prevnum = highblock - 1; bt = (BTRAILER *) TRANBUFF(tx); @@ -126,34 +124,35 @@ int checkproof(TX *tx, word32 *splitblock) stime = get32(bt->stime); time0 = get32(bt->time0); difficulty = get32(bt->difficulty); - if(stime <= time0) BAIL(4); /* bad solve time sequence */ - if(stime > (now + BCONFREQ)) BAIL(5); /* a future block is bad */ + if(difficulty > 255) BAIL(4); + if(stime <= time0) BAIL(5); /* bad solve time sequence */ + if(stime > (now + BCONFREQ)) BAIL(6); /* a future block is bad */ + if(j != 0 && memcmp(bt->phash, (bt - 1)->bhash, HASHLEN)) BAIL(7); if(bt->bnum[0] == 0) continue; /* skip NG block */ - if(diff != INVALID_DIFFICULTY) { - if(difficulty != diff) BAIL(6); /* bad difficulty sequence */ - if(memcmp(bt->phash, (bt - 1)->bhash, HASHLEN)) BAIL(7); + if(diff != INVALID_DIFF) { + if(difficulty != diff) BAIL(8); /* bad difficulty sequence */ } - /* stime must increase */ if(j != 0) { - if(stime <= (s = get32((bt - 1)->stime))) BAIL(8); - if(time0 != s) BAIL(9); /* time0 must == the previous stime */ + /* stime must increase */ + if(stime <= (s = get32((bt - 1)->stime))) BAIL(9); + if(time0 != s) BAIL(10); /* time0 must == the previous stime */ } if(get32(bt->tcount) != 0) { /* bt is not a pseudoblock so check work: */ if(cmp64(bt->bnum, v24trigger) > 0) { /* v2.4 */ - if(peach(bt, difficulty, NULL, 1)) BAIL(10); + if(peach(bt, difficulty, NULL, 1)) BAIL(11); } else { /* v2.3 and prior */ - if(trigg_check(bt->mroot, difficulty, bt->bnum) == NULL) BAIL(11); + if(trigg_check(bt->mroot, difficulty, bt->bnum) == NULL) BAIL(12); } } add_weight2(weight, difficulty); /* tally peer's chain weight */ /* Compute diff = next difficulty to check next peer trailer. */ diff = set_difficulty(difficulty, stime - time0, stime, (byte *) tnum); - if(!Running) BAIL(12); + if(!Running) BAIL(13); } /* end for j, bt -- proof trailers check */ - if(memcmp(weight, tx->weight, 32)) BAIL(13); /* their weight is bad */ + if(memcmp(weight, tx->weight, 32)) BAIL(14); /* their weight is bad */ /* Scan through trailer array to find where chain splits: splitblock */ bt = (BTRAILER *) TRANBUFF(tx); @@ -166,11 +165,11 @@ int checkproof(TX *tx, word32 *splitblock) *splitblock = tnum[0]; /* return first non-matching block number */ break; } - if(!Running) BAIL(14); + if(!Running) BAIL(15); /* trailers match -- continue scan */ } /* end for j, bt -- split detection */ - if(j == 0) BAIL(15); /* never matched -- should not happen */ - if(j >= NTFTX) BAIL(16); /* no split found -- should not happen */ + if(j == 0) BAIL(16); /* never matched -- should not happen */ + if(j >= NTFTX) BAIL(17); /* no split found -- should not happen */ allow: if(Trace) plog("checkproof() splitblock = 0x%x", *splitblock); return VEOK; /* allow syncup() to run */ diff --git a/src/pval.c b/src/pval.c index cd7ee466..054b0cb3 100644 --- a/src/pval.c +++ b/src/pval.c @@ -34,7 +34,7 @@ int pval(char *fname) /* read trailer */ if(fseek(fp, -(sizeof(BTRAILER)), SEEK_END)) BAIL(6); if(fread(&bt, sizeof(BTRAILER), 1, fp) != 1) BAIL(7); - fclose(fp); /* was opened by bval() */ + fclose(fp); fp = NULL; /* check zeros */ @@ -80,8 +80,6 @@ int bridge(void) FILE *fp = NULL; int message; - if(Cblocknum[0] == 0xfe) BAIL(1); /* internal error */ - if(Trace) plog("Making pblock.dat..."); fp = fopen("pblock.dat", "wb"); diff --git a/src/server.c b/src/server.c index cde53c74..78dac835 100644 --- a/src/server.c +++ b/src/server.c @@ -17,7 +17,7 @@ int server(void) { static time_t nsd_time; /* event timers */ - static time_t bctime, mwtime, mqtime, sftime; + static time_t bctime, mwtime, mqtime, sftime, vtime; static time_t ipltime; static SOCKET lsd, nsd; static NODE *np, node; @@ -26,7 +26,6 @@ int server(void) static pid_t pid; /* child pid */ static int lfd; /* for lock() */ static word32 hps; /* same as Hps in monitor.c */ - static word32 bigwait; Running = 1; /* globals are in data.c */ @@ -39,9 +38,9 @@ int server(void) Utime = Ltime; /* for watchdog timer */ Watchdog = WATCHTIME + (rand2() % 600); Bridgetime = Time0 + BRIDGE; /* pseudo-block timer */ - bigwait = (60*60*3) + (rand2() % 10800); /* between 3 and 6 hours */ ipltime = Ltime + (rand2() % 300) + 10; /* ip list fetch time */ sftime = Ltime + (rand2() % 300) + 300; /* send_found() time */ + vtime = Ltime + 4; /* Verisimility restart check time */ if((lsd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) fatal("Cannot open listening socket."); @@ -282,13 +281,14 @@ int server(void) if(Monitor && !Bgflag) monitor(); if(Watchdog && (Ltime - Utime) >= Watchdog) { - if(Cblocknum[0] != 0xfe || (Ltime - Utime) >= bigwait) { - restart("watchdog"); - } + restart("watchdog"); } /* Check for restart signal from Verisimility every 4 seconds */ - if((Ltime & 3) == 0 && exists("vstart.tmp")) restart("Verisimility"); + if(Ltime >= vtime) { + if(exists("vstart.lck")) restart("Verisimility"); + vtime += 4; + } if(Ltime >= ipltime) { refresh_ipl(); /* refresh ip list */ diff --git a/src/syncup.c b/src/syncup.c index 02bbdce0..006106da 100644 --- a/src/syncup.c +++ b/src/syncup.c @@ -23,6 +23,7 @@ int syncup(word32 splitblock, byte *txcblock, word32 peerip) NODE *np2; time_t lasttime; + Insyncup = 1; show("syncup"); if(Bcpid) { /* Wait for block constructor to exit... */ if(Trace) plog("syncup(): Waiting for bcon to exit..."); @@ -116,7 +117,7 @@ int syncup(word32 splitblock, byte *txcblock, word32 peerip) if(Trace) plog("Download and update missing blocks from peer..."); put64(bnum, sblock); for(j = 0; ; ) { - if(bnum[0] == 0) add64(bnum, One, bnum); /* don't get NG block */ + if(bnum[0] == 0) add64(bnum, One, bnum); /* skip NG blocks */ sprintf(buff, "b%s.bc", bnum2hex(bnum)); if(j == 60) { if(Trace) plog("syncup(): failed while downloading %s from %s", @@ -143,6 +144,7 @@ int syncup(word32 splitblock, byte *txcblock, word32 peerip) if(result) plog("syncup(): tfval() error: %d", result); memcpy(Weight, tfweight, HASHLEN); if(result == 0) plog("syncup() is good!"); + Insyncup = 0; return VEOK; badsyncup: @@ -156,5 +158,6 @@ int syncup(word32 splitblock, byte *txcblock, word32 peerip) reset_difficulty(NULL, Bcdir); /* reset Difficulty and others */ memcpy(Weight, saveweight, HASHLEN); le_open("ledger.dat", "rb"); + Insyncup = 0; return VEOK; } /* end syncup() */ diff --git a/src/tag.c b/src/tag.c index cf1d3343..88d972f2 100644 --- a/src/tag.c +++ b/src/tag.c @@ -4,7 +4,7 @@ * See LICENSE.PDF **** NO WARRANTY **** * * Date: 17 May 2018 - * Revised: 2 Sep 2018 + * Revised: 15 December 2019 * */ @@ -24,6 +24,58 @@ #define HAS_TAG(addr) \ (((byte *) (addr))[2196] != 0x42 && ((byte *) (addr))[2196] != 0x00) +byte *Tagidx; /* array of all 12-byte tags in ledger order */ +word32 Ntagidx; /* number of tags in Tagidx[] */ +#define BAIL(m) { message = m; goto bail; } + + +/* Release tag index */ +void tag_free(void) +{ + if(Tagidx != NULL) free(Tagidx); + Tagidx = NULL; + Ntagidx = 0; +} + + +/* Build the tag index, Tagidx[]. + * Return VEOK if success, else error code. + */ +int tag_buildidx(void) +{ + FILE *fp; + LENTRY le; + int message; + word32 n; + byte *tp; + + if(Trace) plog("tag_buildidx()"); + if(Tagidx != NULL) return VEOK; /* index already made */ + + fp = fopen("ledger.dat", "rb"); + if(fp == NULL) BAIL(1); + fseek(fp, 0L, SEEK_END); + Ntagidx = ftell(fp) / sizeof(le); + Tagidx = (byte *) malloc(Ntagidx * ADDR_TAG_LEN); + if(Tagidx == NULL) BAIL(2); /* no memory */ + fseek(fp, 0L, SEEK_SET); + for(tp = Tagidx, n = 0; n < Ntagidx; n++, tp += ADDR_TAG_LEN) { + if(fread(&le, sizeof(le), 1, fp) != 1) break; /* EOF */ + memcpy(tp, ADDR_TAG_PTR(le.addr), ADDR_TAG_LEN); + } + if(n != Ntagidx) BAIL(3); /* I/O error likely */ + fclose(fp); + if(Trace) plog("tag_buildidx() success: Ntagidx = %u", Ntagidx); + return VEOK; /* index built */ +bail: + if(fp != NULL) fclose(fp); + if(Tagidx != NULL) free(Tagidx); + Tagidx = NULL; + Ntagidx = 0; + error("tag_buildidx(): BAIL(%d)\007", message); /* should not happen */ + return message; +} /* end tag_buildidx() */ + /* Search txq1.dat and txclean.dat for a tag matching tag of addr in * some pending TX's change address. @@ -72,58 +124,80 @@ int tag_qfind(byte *addr) } /* end tag_qfind() */ -/* Find the tag of addr in ledger.dat and copy the - * full address to foundaddr. - * Return VEOK if tag found, else VERROR. +#if ADDR_TAG_LEN != 12 + ADDR_TAG_LEN must be 12 for tag code in tag.c tag_find() +#endif + +/* Find the tag of addr in Tagidx[]. + * If foundaddr or balance is not NULL, copy the + * full fields from ledger.dat to foundaddr and/or balance. + * Return VEOK if tag found, VERROR if not found, or + * some other internal error code. */ int tag_find(byte *addr, byte *foundaddr, byte *balance) { FILE *fp; - byte *tag; + byte *tag, *tp; LENTRY le; + word32 n; + int message; - fp = fopen("ledger.dat", "rb"); - if(fp == NULL) return error("tag_find(): Cannot open ledger.dat"); - tag = ADDR_TAG_PTR(addr); - for(;;) { - if(fread(&le, 1, sizeof(LENTRY), fp) != sizeof(LENTRY)) break; - if(memcmp(tag, ADDR_TAG_PTR(le.addr), ADDR_TAG_LEN) == 0) - { - memcpy(foundaddr, le.addr, TXADDRLEN); - if(balance != NULL) - { - memcpy(balance, le.balance, TXAMOUNT); - } + fp = NULL; /* for bail */ + if(Tagidx == NULL) tag_buildidx(); + if(Tagidx == NULL) BAIL(2); /* 2 > VERROR */ - fclose(fp); - return VEOK; /* found */ - } - } - fclose(fp); - return VERROR; /* not found */ + tag = ADDR_TAG_PTR(addr); + /* Search tag index, Tagidx[] for tag. */ + for(tp = Tagidx, n = 0; n < Ntagidx; n++, tp += ADDR_TAG_LEN) { + /* compare tag in Tagidx[] to tag: (about 9 instructions in asm) */ + if( *((word32 *) tp) == *((word32 *) tag) + && *((word32 *) (tp + 4)) == *((word32 *) (tag + 4)) + && *((word32 *) (tp + 8)) == *((word32 *) (tag + 8)) ) { + /* tag found */ + if(foundaddr != NULL || balance != NULL) { + /* and caller wants ledger entry... */ + fp = fopen("ledger.dat", "rb"); + if(fp == NULL) BAIL(3); + /* n is record number in ledger.dat */ + if(fseek(fp, n * sizeof(le), SEEK_SET)) BAIL(4); + if(fread(&le, sizeof(le), 1, fp) != 1) BAIL(5); + if(memcmp(ADDR_TAG_PTR(le.addr), tag, ADDR_TAG_LEN)) BAIL(6); + fclose(fp); + if(foundaddr != NULL) memcpy(foundaddr, le.addr, TXADDRLEN); + if(balance != NULL) memcpy(balance, le.balance, TXAMOUNT); + } /* end if copy entry */ + return VEOK; /* found tag! */ + } /* end if memcmp found */ + } /* end for tp -- search for tag */ + return VERROR; /* tag not found */ +bail: + if(fp != NULL) fclose(fp); + tag_free(); /* Erase the bad index */ + error("tag_find(): BAIL(%d)\007", message); /* should not happen */ + return message; } /* end tag_find() */ /* Validate TX address tags. - * If called from tx_val(), checkq is non-zero in - * order to check queues, txq1.dat and txclean.dat. + * If called from tx_val(), bnum is NULL in order to check + * queues, txq1.dat and txclean.dat, and always do dst check. + * When called from bval.c, bnum is not NULL and is checked + * against tagval_trigger in order to do dst check. * Return VEOK if tags are valid, else VERROR to reject TX. */ -int tag_valid(byte *src_addr, byte *chg_addr, byte *dst_addr, int checkq, byte *bnum) +int tag_valid(byte *src_addr, byte *chg_addr, byte *dst_addr, byte *bnum) { LENTRY le; - word32 tagval_trigger[2]; + static word32 tagval_trigger[2] = { RTRIGGER31, 0 }; /* For v2.0 */ - tagval_trigger[0] = tagval_trigger[1] = 0; - if(checkq == 0 && bnum != NULL) { - tagval_trigger[0] = RTRIGGER31; /* For v2.0 */ - } - if(cmp64(bnum, tagval_trigger) >= 0) { - /* Ignore the below check prior to block 17185... - * src_addr was already found in ledger.dat and dup checked - * by txval or bval. - * - * Check dst_addr. If no dst_tag, dst_addr is valid: */ + if(bnum == NULL || cmp64(bnum, tagval_trigger) >= 0) { + /* Do below check on or after block 17185 when called + * from bval(). If called from tx_val(), always perform + * check. src_addr was already found in ledger.dat and dup + * already checked by txval or bval. + * + * Check dst_addr. If no dst_tag, dst_addr is valid: + */ if(HAS_TAG(dst_addr)) { /* If there is a dst_tag, and its full address is not @@ -134,7 +208,7 @@ int tag_valid(byte *src_addr, byte *chg_addr, byte *dst_addr, int checkq, byte * goto bad; } } - } + } /* end if dst tag check */ /* If no change tag, tx is valid. */ if(!HAS_TAG(chg_addr)) return VEOK; /* If src and chg tags are the same, tx is valid (transfer). */ @@ -149,17 +223,17 @@ int tag_valid(byte *src_addr, byte *chg_addr, byte *dst_addr, int checkq, byte * /* Otherwise, check all queues and ledger.dat for change tag. * First, if change tag is in ledger.dat, tx is invalid. */ - if(tag_find(chg_addr, le.addr, NULL) == VEOK) { + if(tag_find(chg_addr, NULL, NULL) == VEOK) { plog("New CHG_TAG Already Exists in Ledger!"); goto bad; } - if(checkq) { + if(bnum == NULL) { /* If called from tx_val(), * and if tag is in txq1.dat or txclean.dat, tx is invalid. */ if(tag_qfind(chg_addr) == VEOK) { - plog("tag_qfind() returned VEOK"); - goto bad; + plog("Tag is already in queue"); + goto bad; } } if(Trace) plog("Tag created"); @@ -182,7 +256,8 @@ int tag_valid(byte *src_addr, byte *chg_addr, byte *dst_addr, int checkq, byte * * tag string at ADDR_TAG_PTR(np->tx.dst_addr) tag to query * on return: * np->tx.send_total = 1 if found, or 0 if not found. - * np->tx.dst_addr has full found address with tag. + * if found: np->tx.dst_addr has full found address with tag. + * np->tx.change_total has balance. * * Returns VEOK if found, else VERROR. */ @@ -199,11 +274,10 @@ int tag_resolve(NODE *np) memcpy(np->tx.dst_addr, foundaddr, TXADDRLEN); memcpy(np->tx.change_total, balance, TXAMOUNT); put64(np->tx.send_total, One); - ecode = VEOK; } send_op(np, OP_RESOLVE); return ecode; } /* end tag_resolve() */ -#endif /* EXCLUDE_RESOLVE */ +#endif /* !EXCLUDE_RESOLVE */ diff --git a/src/tests/checkproof/testp.c b/src/tests/checkproof/testp.c index f97fc670..0361d6ce 100644 --- a/src/tests/checkproof/testp.c +++ b/src/tests/checkproof/testp.c @@ -3,6 +3,8 @@ int sub_weight(byte *weight, byte difficulty); int past_weight(byte *weight, word32 lownum); + See LICENSE.PDF + Date: 23 November 2019 */ diff --git a/src/tests/checkproof/testp2.c b/src/tests/checkproof/testp2.c index b4d502c5..b2944a8d 100644 --- a/src/tests/checkproof/testp2.c +++ b/src/tests/checkproof/testp2.c @@ -3,6 +3,8 @@ int sub_weight(byte *weight, byte difficulty); int past_weight(byte *weight, word32 lownum); + See LICENSE.PDF + Date: 23 November 2019 */ diff --git a/src/tests/readme.txt b/src/tests/readme.txt new file mode 100644 index 00000000..30173555 --- /dev/null +++ b/src/tests/readme.txt @@ -0,0 +1,4 @@ +This directory contains some test programs for various Mochimo features. +The directory name identifies the feature for which the unit test was created. +For specific questions about any test code, please contact Stackoverflo on +Discord. diff --git a/src/tests/tagindex/ledger.dat.gz b/src/tests/tagindex/ledger.dat.gz new file mode 100644 index 00000000..92d0b05f Binary files /dev/null and b/src/tests/tagindex/ledger.dat.gz differ diff --git a/src/tests/tagindex/testtag.c b/src/tests/tagindex/testtag.c new file mode 100644 index 00000000..bd67364d --- /dev/null +++ b/src/tests/tagindex/testtag.c @@ -0,0 +1,68 @@ +/* testtag.c Test tag index functions + + See LICENSE.PDF + + Date: 15 December 2019 +*/ + +#include "../config.h" +#include "../mochimo.h" +#include "../proto.h" + +#include "../data.c" +#include "../add64.c" +#include "../crypto/crc16.c" +#include "../rand.c" +#include "../error.c" +#include "../util.c" +#include "../ledger.c" +#define EXCLUDE_RESOLVE +#include "../tag.c" + +/* kill mirror() children and grandchildren */ +void stop_mirror(void) +{ + if(Mqpid) { + if(Trace) plog(" Reaping mirror() zombies..."); + kill(Mqpid, SIGTERM); + waitpid(Mqpid, NULL, 0); + Mqpid = 0; + } +} /* end stop_mirror() */ + + +int main() +{ + static LENTRY le; + int status, j; + + Trace = 1; + + printf("sizeof(LENTRY) = %u\n", (int) sizeof(LENTRY)); + strcpy((char *) ADDR_TAG_PTR(le.addr), "badtag"); + printf("tag_find('%-12.12s')\n", (char *) ADDR_TAG_PTR(le.addr)); + status = tag_find(le.addr, le.addr, le.balance); + printf("tag_find() returned %d S/B 1\n", status); + + printf("Tags:\n"); + for(j = 0; j < Ntagidx; j++) { + printf("%d: %-12.12s\n", j, (char *) &Tagidx[j * ADDR_TAG_LEN]); + } + + memset(ADDR_TAG_PTR(le.addr), 0, ADDR_TAG_LEN); + strcpy((char *) ADDR_TAG_PTR(le.addr), "123"); + printf("tag_find('%-12.12s')\n", (char *) ADDR_TAG_PTR(le.addr)); + status = tag_find(le.addr, le.addr, le.balance); + printf("tag_find() returned %d S/B 0\n", status); + printf("le.addr = %-20.20s...\n", le.addr); + printf("le.balance = %u\n", get32(le.balance)); + + tag_free(); + tag_free(); + printf("tag_find('%-12.12s')\n", (char *) ADDR_TAG_PTR(le.addr)); + status = tag_find(le.addr, le.addr, le.balance); + printf("tag_find() returned %d S/B 0\n", status); + tag_buildidx(); + + return 0; +} diff --git a/src/txclean.c b/src/txclean.c index 38e2c675..f10ab4ec 100644 --- a/src/txclean.c +++ b/src/txclean.c @@ -64,7 +64,7 @@ int txclean(void) memcpy(ADDR_TAG_PTR(addr), mtx->dst[j].tag, ADDR_TAG_LEN); mtx->zeros[j] = 0; /* If dst[j] tag not found, put error code in zeros[] array. */ - if(tag_find(addr, addr, NULL) != VEOK) mtx->zeros[j] = 1; + if(tag_find(addr, NULL, NULL) != VEOK) mtx->zeros[j] = 1; } } count = fwrite(&tx, 1, sizeof(TXQENTRY), fpout); diff --git a/src/txval.c b/src/txval.c index 4b99744d..1b3a9c78 100644 --- a/src/txval.c +++ b/src/txval.c @@ -37,7 +37,6 @@ int tx_val(TX *tx) static byte message[HASHLEN]; /* transaction hash for WOTS */ static byte pk2[TXSIGLEN]; /* more WOTS */ static byte rnd2[32]; /* for WOTS addr[] */ - byte bnum[8] = {0}; MTX *mtx; static TX txs; @@ -102,8 +101,7 @@ int tx_val(TX *tx) if(mtx_val(mtx, Myfee)) return 1; /* bad mtx */ } else { if(tag_valid(tx->src_addr, tx->chg_addr, tx->dst_addr, - 1, &bnum[0]) != VEOK) return 1; /* bad tag */ - + NULL) != VEOK) return 1; /* bad tag */ } return 0; /* tx valid */ } /* end tx_val() */ diff --git a/src/update.c b/src/update.c index 5b6a7996..df156b2c 100644 --- a/src/update.c +++ b/src/update.c @@ -4,7 +4,7 @@ * See LICENSE.PDF **** NO WARRANTY **** * * Date: 25 April 2018 - * Updated: 10 May 2019 + * Updated: 15 December 2019 */ /* Creates child to send OP_FOUND to all recent peers */ @@ -143,10 +143,12 @@ word32 gethdrlen(char *fname) int update(char *fname, int mode) { char cmd[100]; + char *solvestr; if(Trace) plog("Entering update()"); if(!exists(fname)) return VERROR; show("update"); + solvestr = NULL; if(Bcpid) { if(Trace) plog(" Waiting for bcon to exit..."); @@ -182,10 +184,14 @@ int update(char *fname, int mode) le_close(); /* close server ledger reference */ if(Trace) plog(" About to call bval and bup..."); - + /* Hotfix for critical bug identified on 09/26/19 */ - if(exists("cblock.lck")) unlink("cblock.lck"); - + if(exists("cblock.lck")) { + unlink("cblock.lck"); + solvestr = "pushed"; + } + + tag_free(); /* Erase Tagidx[] to be rebuilt on next tag_find() call. */ sprintf(cmd, "../bval %s", fname); /* call validator on fname */ system(cmd); if(!exists("vblock.dat")) { /* validation failed */ @@ -229,36 +235,37 @@ int update(char *fname, int mode) bnum2hex(Cblocknum)); } if(CAROUSEL(Cblocknum)) { + tag_free(); /* Erase old in-memory Tagidx[] */ if(renew()) goto err; + txclean(); /* clean the tx queue */ if(le_open("ledger.dat", "rb") != VEOK) goto err; /* reopen */ } } - if(mode == 1) { - if(exists("cblock.lck")) { - unlink("cblock.lck"); - if(Trace) plog("updated pushed block 0x%s", bnum2hex(Cblocknum)); - } - else { - Nsolved++; /* our block */ - write_data(&Nsolved, 4, "solved.dat"); - } + if(mode == 1 && Insyncup == 0 && solvestr == NULL) { /* not "pushed" */ + solvestr = "solved"; + Nsolved++; /* our block */ + write_data(&Nsolved, 4, "solved.dat"); } Stime = Ltime + 20; /* hold status display */ if(!Ininit) { /* synchronous */ if(exists("../update-external.sh")) system("../update-external.sh"); } - if(mode != 2) { + if(mode != 2) { /* not a pseudo-block */ if(!Ininit) { - plog("Block %s: 0x%s", mode ? "solved" : "updated", - bnum2hex(Cblocknum)); - if(!Bgflag) printf("Solved: %u Haiku/second: %lu Difficulty: %d\n", - Nsolved, (unsigned long) Hps, Difficulty); - Nupdated++; + if(Insyncup) plog("Syncing Block: 0x%s", bnum2hex(Cblocknum)); + else { + if(solvestr == NULL) solvestr = "updated"; + plog("Block %s: 0x%s", solvestr, bnum2hex(Cblocknum)); + if(!Bgflag) + printf("Solved: %u Haiku/second: %lu Difficulty: %d\n", + Nsolved, (unsigned long) Hps, Difficulty); + Nupdated++; + } /* end if !Insyncup */ Utime = time(NULL); /* update time for watchdog */ - } - } - Bridgetime = Time0 + BRIDGE; + } /* end if !Ininit */ + } /* end if not-pseudo-block */ + Bridgetime = Time0 + BRIDGE; /* advance pseudo-block timer */ return VEOK; err: restart("update error!");