I have been playing with bitcoind, trying to get it working on OpenBSD. I have stumbled on some bugs that have been fixed. One included the use of rand(), which caused all the wallet unit tests to fail.
https://github.com/bitcoin/bitcoin/pull/2312 This also fixed the other BSDs and Windows as well, I believe. Anyway, they last huge bug I am tracking down is data corruption in my btree files from db4. They recommended I try the latest code which replaces Berekely DB with Google's Leveldb. I still get corruption. The good news is, leveldb comes with unit tests. The corruption_test fails almost immediately with OpenBSD, but passes on Linux and FreeBSD. I sifted through the code and created a test to attempt to emulate what it is doing, which I've included below. I am not sure if this is the cause of the corruption, but the output is different on OpenBSD than on with FreeBSD, Linux, and NetBSD. On FreeBSD, Linux, and NetBSD, the second fread outputs 43. On OpenBSD, it outputs 00. /* * Code */ #include <sys/types.h> #include <sys/mman.h> #include <fcntl.h> #include <err.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int do_open(void); FILE *do_fopen(void); void *do_mmap(int, size_t, off_t); void do_munmap(void *, size_t); const char *fname = "/tmp/mmaptest"; int do_open(void) { int fd; fd = open(fname, O_CREAT | O_RDWR | O_TRUNC, 0644); if (fd == -1) err(1, "open"); printf("do_open: %d\n", fd); return (fd); } FILE * do_fopen(void) { FILE *fp; fp = fopen(fname, "r"); if (fp == NULL) err(1, "fopen"); printf("do_fopen: %d\n", fileno(fp)); return (fp); } void * do_mmap(int fd, size_t len, off_t off) { void *ptr; if (ftruncate(fd, off + len) == -1) err(1, "ftruncate"); ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, off); if (ptr == MAP_FAILED) err(1, "mmap"); printf("MMAP %p fd:%d len:%zu offset:%lld\n", ptr, fd, len, off); return (ptr); } void do_munmap(void *ptr, size_t len) { if (munmap(ptr, len) == -1) err(1, "munmap"); printf("UMAP %p len:%zu\n", ptr, len); } int main(void) { int fd1, fd2; char *ptr1, *ptr2; FILE *fp; char readbuf[32768], writebuf[] = "this is a test"; size_t bytes; fd1 = do_open(); ptr1 = do_mmap(fd1, 65536, 0); memset(ptr1, 'A', 65536); do_munmap(ptr1, 65536); ptr1 = do_mmap(fd1, 131072, 65536); memset(ptr1, 'B', 32768); fp = do_fopen(); bytes = fread(readbuf, 1, sizeof(readbuf), fp); printf("fread %zu bytes, readbuf[1024] = %02x\n", bytes, readbuf[1024]); fclose(fp); fd2 = do_open(); ptr2 = do_mmap(fd2, 65536, 0); memset(ptr2, 'C', 65536); do_munmap(ptr2, 65536); ptr2 = do_mmap(fd2, 131072, 65536); memset(ptr2, 'D', 65536); do_munmap(ptr2, 65536); close(fd2); fp = do_fopen(); bytes = fread(readbuf, 1, sizeof(readbuf), fp); printf("fread %zu bytes, readbuf[1024] = %02x\n", bytes, readbuf[1024]); fclose(fp); fd2 = do_open(); ptr2 = do_mmap(fd2, 65536, 0); memset(ptr2, 'E', 2048); do_munmap(ptr2, 65536); ptr2 = do_mmap(fd2, 131072, 65536); memset(ptr2, 'F', 4096); do_munmap(ptr2, 131072); do_munmap(ptr1, 131072); ftruncate(fd1, 100000); close(fd1); return (0); }
