[Pkg-bitcoin-commits] [libblkmaker] 01/01: Imported Upstream version 0.4.0
Dmitry Smirnov
onlyjob at moszumanska.debian.org
Sat Jun 7 05:31:21 UTC 2014
This is an automated email from the git hooks/post-receive script.
onlyjob pushed a commit to branch upstream
in repository libblkmaker.
commit adcd4f4 (upstream)
Author: Dmitry Smirnov <onlyjob at member.fsf.org>
Date: Sat Jun 7 05:29:25 2014
Imported Upstream version 0.4.0
---
COPYING | 2 +-
ChangeLog | 148 +++++++++++++++++++++
INSTALL | 370 -----------------------------------------------------
NEWS | 0
README | 14 +-
blkmaker.c | 207 ++++++++++++++++++++++++++----
blkmaker.h | 5 +-
blkmaker_jansson.c | 17 ++-
blktemplate.c | 8 +-
blktemplate.h | 5 +
configure.ac | 7 +-
private.h | 15 +++
12 files changed, 385 insertions(+), 413 deletions(-)
diff --git a/COPYING b/COPYING
index 3b5c6d0..f24e654 100644
--- a/COPYING
+++ b/COPYING
@@ -1,4 +1,4 @@
-Copyright (c) 2012 Luke Dashjr
+Copyright 2012-2014 Luke Dashjr
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/ChangeLog b/ChangeLog
index bc35c70..646954b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,157 @@
+2014-05-26 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Merge commit '1cbe9c3'
+
+2014-05-26 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Bugfix: Optimise building merkle branches for no-transactions case, avoiding a malloc(0)
+
+2014-05-07 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Bump versions for 0.4.0
+
+2014-05-03 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Merge branch 'work2d'
+
+2014-05-03 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * blkmk_get_mdata: Accept can_roll_ntime as an argument
+
+2014-02-27 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Add blkmk_append_coinbase_safe2 which can understand mdata use
+
+2014-02-27 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Add blkmk_get_mdata function for miners which need to build the merkle root themselves
+
+2014-02-27 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Optimise merkle root creation by reusing a merkle branch
+
+2014-02-27 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Internal code abstraction into blkmk_set_times
+
+2014-02-27 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Merge branch '0.3.x'
+
+2014-02-27 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Merge branch '0.2.x' into 0.3.x
+
+2014-02-27 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Merge branch '0.1.x' into 0.2.x
+
+2014-02-27 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Implement blkmk_get_data's out_expire argument
+
+2014-02-24 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Merge branch '0.3.x'
+
+2014-02-24 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Merge branch '0.2.x' into 0.3.x
+
+2014-02-24 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Merge branch '0.1.x' into 0.2.x
+
+2014-02-24 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Bugfix: Provide correctly-ordered transaction hash (using new key hash_ for backward compatibility)
+
+2014-01-19 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Update copyright headers
+
+2014-01-19 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Merge branch '0.3.x'
+
+2014-01-19 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Merge branch '0.3.x' (early part)
+
+2014-01-19 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Merge branch '0.3.x' (early part)
+
+2014-01-19 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Merge branch '0.2.x' into 0.3.x
+
+2014-01-19 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Merge branch '0.2.x' (early part) into 0.3.x
+
+2014-01-19 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Null-Merge branch '0.2.x' (early part) into 0.3.x
+
+2014-01-19 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Merge branch '0.1.x' into 0.2.x
+
+2014-01-19 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Merge branch '0.1.x' (early part) into 0.2.x
+
+2014-01-19 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Null-Merge tag 'v0.1.5' into 0.2.x
+
+2014-01-19 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Update copyright headers
+
+2014-01-19 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Remove autogenerated INSTALL and unused ChangeLog/NEWS files from git
+
+2014-01-19 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * COPYING: Update copyright year to 2014
+
+2014-01-19 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Build silently when supported by automake
+
+2014-01-19 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Bugfix: blkmk_init_generation2 needs a return value
+
+2014-01-14 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Bugfix: Avoid breaking strict aliasing rules by copying nonce with memcpy
+
+2013-08-28 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Merge branch '0.3.x'
+
2013-08-24 Luke Dashjr <luke-jr+git at utopios.org>
* Bump libtool version for 0.3.2
2013-08-24 Luke Dashjr <luke-jr+git at utopios.org>
+ * Bump libtool version for 0.2.4
+
+2013-08-24 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * Bump libtool version for 0.1.5
+
+2013-08-24 Luke Dashjr <luke-jr+git at utopios.org>
+
+ * blkmk_init_generation3 capable of overriding a provided coinbasetxn if the generation mutation is allowed
+
+2013-08-24 Luke Dashjr <luke-jr+git at utopios.org>
+
* Merge branch '0.2.x' into 0.3.x
2013-08-24 Luke Dashjr <luke-jr+git at utopios.org>
diff --git a/INSTALL b/INSTALL
deleted file mode 100644
index a1e89e1..0000000
--- a/INSTALL
+++ /dev/null
@@ -1,370 +0,0 @@
-Installation Instructions
-*************************
-
-Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation,
-Inc.
-
- Copying and distribution of this file, with or without modification,
-are permitted in any medium without royalty provided the copyright
-notice and this notice are preserved. This file is offered as-is,
-without warranty of any kind.
-
-Basic Installation
-==================
-
- Briefly, the shell commands `./configure; make; make install' should
-configure, build, and install this package. The following
-more-detailed instructions are generic; see the `README' file for
-instructions specific to this package. Some packages provide this
-`INSTALL' file but do not implement all of the features documented
-below. The lack of an optional feature in a given package is not
-necessarily a bug. More recommendations for GNU packages can be found
-in *note Makefile Conventions: (standards)Makefile Conventions.
-
- The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation. It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions. Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, and a
-file `config.log' containing compiler output (useful mainly for
-debugging `configure').
-
- It can also use an optional file (typically called `config.cache'
-and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring. Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.
-
- If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release. If you are using the cache, and at
-some point `config.cache' contains results you don't want to keep, you
-may remove or edit it.
-
- The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'. You need `configure.ac' if
-you want to change it or regenerate `configure' using a newer version
-of `autoconf'.
-
- The simplest way to compile this package is:
-
- 1. `cd' to the directory containing the package's source code and type
- `./configure' to configure the package for your system.
-
- Running `configure' might take a while. While running, it prints
- some messages telling which features it is checking for.
-
- 2. Type `make' to compile the package.
-
- 3. Optionally, type `make check' to run any self-tests that come with
- the package, generally using the just-built uninstalled binaries.
-
- 4. Type `make install' to install the programs and any data files and
- documentation. When installing into a prefix owned by root, it is
- recommended that the package be configured and built as a regular
- user, and only the `make install' phase executed with root
- privileges.
-
- 5. Optionally, type `make installcheck' to repeat any self-tests, but
- this time using the binaries in their final installed location.
- This target does not install anything. Running this target as a
- regular user, particularly if the prior `make install' required
- root privileges, verifies that the installation completed
- correctly.
-
- 6. You can remove the program binaries and object files from the
- source code directory by typing `make clean'. To also remove the
- files that `configure' created (so you can compile the package for
- a different kind of computer), type `make distclean'. There is
- also a `make maintainer-clean' target, but that is intended mainly
- for the package's developers. If you use it, you may have to get
- all sorts of other programs in order to regenerate files that came
- with the distribution.
-
- 7. Often, you can also type `make uninstall' to remove the installed
- files again. In practice, not all packages have tested that
- uninstallation works correctly, even though it is required by the
- GNU Coding Standards.
-
- 8. Some packages, particularly those that use Automake, provide `make
- distcheck', which can by used by developers to test that all other
- targets like `make install' and `make uninstall' work correctly.
- This target is generally not run by end users.
-
-Compilers and Options
-=====================
-
- Some systems require unusual options for compilation or linking that
-the `configure' script does not know about. Run `./configure --help'
-for details on some of the pertinent environment variables.
-
- You can give `configure' initial values for configuration parameters
-by setting variables in the command line or in the environment. Here
-is an example:
-
- ./configure CC=c99 CFLAGS=-g LIBS=-lposix
-
- *Note Defining Variables::, for more details.
-
-Compiling For Multiple Architectures
-====================================
-
- You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory. To do this, you can use GNU `make'. `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script. `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'. This
-is known as a "VPATH" build.
-
- With a non-GNU `make', it is safer to compile the package for one
-architecture at a time in the source code directory. After you have
-installed the package for one architecture, use `make distclean' before
-reconfiguring for another architecture.
-
- On MacOS X 10.5 and later systems, you can create libraries and
-executables that work on multiple system types--known as "fat" or
-"universal" binaries--by specifying multiple `-arch' options to the
-compiler but only a single `-arch' option to the preprocessor. Like
-this:
-
- ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
- CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
- CPP="gcc -E" CXXCPP="g++ -E"
-
- This is not guaranteed to produce working output in all cases, you
-may have to build one architecture at a time and combine the results
-using the `lipo' tool if you have problems.
-
-Installation Names
-==================
-
- By default, `make install' installs the package's commands under
-`/usr/local/bin', include files under `/usr/local/include', etc. You
-can specify an installation prefix other than `/usr/local' by giving
-`configure' the option `--prefix=PREFIX', where PREFIX must be an
-absolute file name.
-
- You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files. If you
-pass the option `--exec-prefix=PREFIX' to `configure', the package uses
-PREFIX as the prefix for installing programs and libraries.
-Documentation and other data files still use the regular prefix.
-
- In addition, if you use an unusual directory layout you can give
-options like `--bindir=DIR' to specify different values for particular
-kinds of files. Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them. In general, the
-default for these options is expressed in terms of `${prefix}', so that
-specifying just `--prefix' will affect all of the other directory
-specifications that were not explicitly provided.
-
- The most portable way to affect installation locations is to pass the
-correct locations to `configure'; however, many packages provide one or
-both of the following shortcuts of passing variable assignments to the
-`make install' command line to change installation locations without
-having to reconfigure or recompile.
-
- The first method involves providing an override variable for each
-affected directory. For example, `make install
-prefix=/alternate/directory' will choose an alternate location for all
-directory configuration variables that were expressed in terms of
-`${prefix}'. Any directories that were specified during `configure',
-but not in terms of `${prefix}', must each be overridden at install
-time for the entire installation to be relocated. The approach of
-makefile variable overrides for each directory variable is required by
-the GNU Coding Standards, and ideally causes no recompilation.
-However, some platforms have known limitations with the semantics of
-shared libraries that end up requiring recompilation when using this
-method, particularly noticeable in packages that use GNU Libtool.
-
- The second method involves providing the `DESTDIR' variable. For
-example, `make install DESTDIR=/alternate/directory' will prepend
-`/alternate/directory' before all installation names. The approach of
-`DESTDIR' overrides is not required by the GNU Coding Standards, and
-does not work on platforms that have drive letters. On the other hand,
-it does better at avoiding recompilation issues, and works well even
-when some directory options were not specified in terms of `${prefix}'
-at `configure' time.
-
-Optional Features
-=================
-
- If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
- Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System). The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
- For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
- Some packages offer the ability to configure how verbose the
-execution of `make' will be. For these packages, running `./configure
---enable-silent-rules' sets the default to minimal output, which can be
-overridden with `make V=1'; while running `./configure
---disable-silent-rules' sets the default to verbose, which can be
-overridden with `make V=0'.
-
-Particular systems
-==================
-
- On HP-UX, the default C compiler is not ANSI C compatible. If GNU
-CC is not installed, it is recommended to use the following options in
-order to use an ANSI C compiler:
-
- ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
-
-and if that doesn't work, install pre-built binaries of GCC for HP-UX.
-
- HP-UX `make' updates targets which have the same time stamps as
-their prerequisites, which makes it generally unusable when shipped
-generated files such as `configure' are involved. Use GNU `make'
-instead.
-
- On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
-parse its `<wchar.h>' header file. The option `-nodtk' can be used as
-a workaround. If GNU CC is not installed, it is therefore recommended
-to try
-
- ./configure CC="cc"
-
-and if that doesn't work, try
-
- ./configure CC="cc -nodtk"
-
- On Solaris, don't put `/usr/ucb' early in your `PATH'. This
-directory contains several dysfunctional programs; working variants of
-these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
-in your `PATH', put it _after_ `/usr/bin'.
-
- On Haiku, software installed for all users goes in `/boot/common',
-not `/usr/local'. It is recommended to use the following options:
-
- ./configure --prefix=/boot/common
-
-Specifying the System Type
-==========================
-
- There may be some features `configure' cannot figure out
-automatically, but needs to determine by the type of machine the package
-will run on. Usually, assuming the package is built to be run on the
-_same_ architectures, `configure' can figure that out, but if it prints
-a message saying it cannot guess the machine type, give it the
-`--build=TYPE' option. TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name which has the form:
-
- CPU-COMPANY-SYSTEM
-
-where SYSTEM can have one of these forms:
-
- OS
- KERNEL-OS
-
- See the file `config.sub' for the possible values of each field. If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the machine type.
-
- If you are _building_ compiler tools for cross-compiling, you should
-use the option `--target=TYPE' to select the type of system they will
-produce code for.
-
- If you want to _use_ a cross compiler, that generates code for a
-platform different from the build platform, you should specify the
-"host" platform (i.e., that on which the generated programs will
-eventually be run) with `--host=TYPE'.
-
-Sharing Defaults
-================
-
- If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists. Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Defining Variables
-==================
-
- Variables not defined in a site shell script can be set in the
-environment passed to `configure'. However, some packages may run
-configure again during the build, and the customized values of these
-variables may be lost. In order to avoid this problem, you should set
-them in the `configure' command line, using `VAR=value'. For example:
-
- ./configure CC=/usr/local2/bin/gcc
-
-causes the specified `gcc' to be used as the C compiler (unless it is
-overridden in the site shell script).
-
-Unfortunately, this technique does not work for `CONFIG_SHELL' due to
-an Autoconf bug. Until the bug is fixed you can use this workaround:
-
- CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
-
-`configure' Invocation
-======================
-
- `configure' recognizes the following options to control how it
-operates.
-
-`--help'
-`-h'
- Print a summary of all of the options to `configure', and exit.
-
-`--help=short'
-`--help=recursive'
- Print a summary of the options unique to this package's
- `configure', and exit. The `short' variant lists options used
- only in the top level, while the `recursive' variant lists options
- also present in any nested packages.
-
-`--version'
-`-V'
- Print the version of Autoconf used to generate the `configure'
- script, and exit.
-
-`--cache-file=FILE'
- Enable the cache: use and save the results of the tests in FILE,
- traditionally `config.cache'. FILE defaults to `/dev/null' to
- disable caching.
-
-`--config-cache'
-`-C'
- Alias for `--cache-file=config.cache'.
-
-`--quiet'
-`--silent'
-`-q'
- Do not print messages saying which checks are being made. To
- suppress all normal output, redirect it to `/dev/null' (any error
- messages will still be shown).
-
-`--srcdir=DIR'
- Look for the package's source code in directory DIR. Usually
- `configure' can determine that directory automatically.
-
-`--prefix=DIR'
- Use DIR as the installation prefix. *note Installation Names::
- for more details, including other options available for fine-tuning
- the installation locations.
-
-`--no-create'
-`-n'
- Run the configure checks, but stop before creating any output
- files.
-
-`configure' also accepts some other, not widely useful, options. Run
-`configure --help' for more details.
-
diff --git a/NEWS b/NEWS
deleted file mode 100644
index e69de29..0000000
diff --git a/README b/README
index d5820a2..1f6f5bf 100644
--- a/README
+++ b/README
@@ -10,7 +10,13 @@ Note that you must assign blkmk_sha256_impl to a function pointer:
bool mysha256(void *hash_out, const void *data, size_t datasz)
hash_out must be able to overlap with data!
-Also note that you should NOT roll ntime for data retrieved; while it will
-probably work, there is no guarantee it won't fall outside the maxtime limits
-for the blocktemplate. It is usually best to simply get more data as often
-as it is needed.
+Also note that you should NOT roll ntime for data retrieved without explicitly
+checking that it falls within the template's limitations (mintime, maxtime,
+mintimeoff, and maxtimeoff); read the BIP 23 specification in detail to
+understand how they work. It is usually best to simply get more data as often
+as it is needed. For blkmk_get_mdata, you may specify that you intend to roll
+the ntime header exactly once per second past usetime - it will then set
+*out_expires such that the expiration occurs before you roll beyond any ntime
+limits. If you are rolling ntime at any rate other than once per second, you
+should NOT specify can_roll_ntime to blkmk_get_mdata, and must check that your
+usage falls within the explicit template limits yourself.
diff --git a/blkmaker.c b/blkmaker.c
index 1bb6e28..2a6eaf3 100644
--- a/blkmaker.c
+++ b/blkmaker.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 Luke Dashjr
+ * Copyright 2012-2014 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.
@@ -41,16 +41,14 @@ bool _blkmk_dblsha256(void *hash, const void *data, size_t datasz) {
#define dblsha256 _blkmk_dblsha256
-uint64_t blkmk_init_generation2(blktemplate_t *tmpl, void *script, size_t scriptsz, bool *out_newcb) {
- if (tmpl->cbtxn)
+uint64_t blkmk_init_generation3(blktemplate_t * const tmpl, const void * const script, const size_t scriptsz, bool * const inout_newcb) {
+ if (tmpl->cbtxn && !(*inout_newcb && (tmpl->mutations & BMM_GENERATE)))
{
- if (out_newcb)
- *out_newcb = false;
+ *inout_newcb = false;
return 0;
}
- if (out_newcb)
- *out_newcb = true;
+ *inout_newcb = true;
size_t datasz = 62 + sizeof(blkheight_t) + scriptsz;
unsigned char *data = malloc(datasz);
@@ -101,6 +99,11 @@ uint64_t blkmk_init_generation2(blktemplate_t *tmpl, void *script, size_t script
txn->data = data;
txn->datasz = off;
+ if (tmpl->cbtxn)
+ {
+ _blktxn_free(tmpl->cbtxn);
+ free(tmpl->cbtxn);
+ }
tmpl->cbtxn = txn;
tmpl->mutations |= BMM_CBAPPEND | BMM_CBSET | BMM_GENERATE;
@@ -108,35 +111,107 @@ uint64_t blkmk_init_generation2(blktemplate_t *tmpl, void *script, size_t script
return tmpl->cbvalue;
}
+uint64_t blkmk_init_generation2(blktemplate_t *tmpl, void *script, size_t scriptsz, bool *out_newcb) {
+ bool tmp;
+ if (!out_newcb)
+ out_newcb = &tmp;
+ *out_newcb = false;
+ return blkmk_init_generation3(tmpl, script, scriptsz, out_newcb);
+}
+
uint64_t blkmk_init_generation(blktemplate_t *tmpl, void *script, size_t scriptsz) {
return blkmk_init_generation2(tmpl, script, scriptsz, NULL);
}
static
-bool build_merkle_root(unsigned char *mrklroot_out, blktemplate_t *tmpl, unsigned char *cbtxndata, size_t cbtxndatasz) {
+bool blkmk_hash_transactions(blktemplate_t * const tmpl)
+{
+ for (unsigned long i = 0; i < tmpl->txncount; ++i)
+ {
+ struct blktxn_t * const txn = &tmpl->txns[i];
+ if (txn->hash_)
+ continue;
+ txn->hash_ = malloc(sizeof(*txn->hash_));
+ if (!dblsha256(txn->hash_, txn->data, txn->datasz))
+ {
+ free(txn->hash_);
+ return false;
+ }
+ }
+ return true;
+}
+
+static
+bool blkmk_build_merkle_branches(blktemplate_t * const tmpl)
+{
+ int branchcount, i;
+ libblkmaker_hash_t *branches;
+
+ if (tmpl->_mrklbranch)
+ return true;
+
+ if (!blkmk_hash_transactions(tmpl))
+ return false;
+
+ branchcount = blkmk_flsl(tmpl->txncount);
+ if (!branchcount)
+ {
+ tmpl->_mrklbranchcount = 0;
+ tmpl->_mrklbranch = NULL;
+ return true;
+ }
+
+ branches = malloc(branchcount * sizeof(*branches));
+
size_t hashcount = tmpl->txncount + 1;
unsigned char hashes[(hashcount + 1) * 32];
- if (!dblsha256(&hashes[0], cbtxndata, cbtxndatasz))
- return false;
- for (unsigned long i = 0; i < tmpl->txncount; ++i)
- if (!dblsha256(&hashes[32 * (i + 1)], tmpl->txns[i].data, tmpl->txns[i].datasz))
- return false;
+ for (i = 0; i < tmpl->txncount; ++i)
+ memcpy(&hashes[0x20 * (i + 1)], tmpl->txns[i].hash_, 0x20);
- while (hashcount > 1)
+ for (i = 0; i < branchcount; ++i)
{
+ memcpy(&branches[i], &hashes[0x20], 0x20);
if (hashcount % 2)
{
memcpy(&hashes[32 * hashcount], &hashes[32 * (hashcount - 1)], 32);
++hashcount;
}
- for (size_t i = 0; i < hashcount; i += 2)
+ for (size_t i = 2; i < hashcount; i += 2)
// This is where we overlap input and output, on the first pair
if (!dblsha256(&hashes[i / 2 * 32], &hashes[32 * i], 64))
+ {
+ free(branches);
return false;
+ }
hashcount /= 2;
}
+ tmpl->_mrklbranch = branches;
+ tmpl->_mrklbranchcount = branchcount;
+
+ return true;
+}
+
+static
+bool build_merkle_root(unsigned char *mrklroot_out, blktemplate_t *tmpl, unsigned char *cbtxndata, size_t cbtxndatasz) {
+ int i;
+ libblkmaker_hash_t hashes[0x40];
+
+ if (!blkmk_build_merkle_branches(tmpl))
+ return false;
+
+ if (!dblsha256(&hashes[0], cbtxndata, cbtxndatasz))
+ return false;
+
+ for (i = 0; i < tmpl->_mrklbranchcount; ++i)
+ {
+ memcpy(&hashes[1], tmpl->_mrklbranch[i], 0x20);
+ // This is where we overlap input and output, on the first pair
+ if (!dblsha256(&hashes[0], &hashes[0], 0x40))
+ return false;
+ }
+
memcpy(mrklroot_out, &hashes[0], 32);
return true;
@@ -145,7 +220,7 @@ bool build_merkle_root(unsigned char *mrklroot_out, blktemplate_t *tmpl, unsigne
static const int cbScriptSigLen = 4 + 1 + 36;
static
-bool _blkmk_append_cb(blktemplate_t *tmpl, void *vout, const void *append, size_t appendsz) {
+bool _blkmk_append_cb(blktemplate_t * const tmpl, void * const vout, const void * const append, const size_t appendsz, size_t * const appended_at_offset) {
unsigned char *out = vout;
unsigned char *in = tmpl->cbtxn->data;
size_t insz = tmpl->cbtxn->datasz;
@@ -154,6 +229,8 @@ bool _blkmk_append_cb(blktemplate_t *tmpl, void *vout, const void *append, size_
return false;
int cbPostScriptSig = cbScriptSigLen + 1 + in[cbScriptSigLen];
+ if (appended_at_offset)
+ *appended_at_offset = cbPostScriptSig;
unsigned char *outPostScriptSig = &out[cbPostScriptSig];
void *outExtranonce = (void*)outPostScriptSig;
outPostScriptSig += appendsz;
@@ -172,12 +249,21 @@ bool _blkmk_append_cb(blktemplate_t *tmpl, void *vout, const void *append, size_
return true;
}
-ssize_t blkmk_append_coinbase_safe(blktemplate_t *tmpl, const void *append, size_t appendsz) {
+ssize_t blkmk_append_coinbase_safe2(blktemplate_t * const tmpl, const void * const append, const size_t appendsz, int extranoncesz, const bool merkle_only)
+{
if (!(tmpl->mutations & (BMM_CBAPPEND | BMM_CBSET)))
return -1;
size_t datasz = tmpl->cbtxn->datasz;
- size_t availsz = 100 - sizeof(unsigned int) - tmpl->cbtxn->data[cbScriptSigLen];
+ if (!merkle_only)
+ {
+ if (extranoncesz < sizeof(unsigned int))
+ extranoncesz = sizeof(unsigned int);
+ else
+ if (extranoncesz == sizeof(unsigned int))
+ ++extranoncesz;
+ }
+ size_t availsz = 100 - extranoncesz - tmpl->cbtxn->data[cbScriptSigLen];
if (appendsz > availsz)
return availsz;
@@ -186,13 +272,17 @@ ssize_t blkmk_append_coinbase_safe(blktemplate_t *tmpl, const void *append, size
return -2;
tmpl->cbtxn->data = newp;
- if (!_blkmk_append_cb(tmpl, newp, append, appendsz))
+ if (!_blkmk_append_cb(tmpl, newp, append, appendsz, NULL))
return -3;
tmpl->cbtxn->datasz += appendsz;
return availsz;
}
+ssize_t blkmk_append_coinbase_safe(blktemplate_t * const tmpl, const void * const append, const size_t appendsz) {
+ return blkmk_append_coinbase_safe2(tmpl, append, appendsz, 0, false);
+}
+
bool _blkmk_extranonce(blktemplate_t *tmpl, void *vout, unsigned int workid, size_t *offs) {
unsigned char *in = tmpl->cbtxn->data;
size_t insz = tmpl->cbtxn->datasz;
@@ -204,7 +294,7 @@ bool _blkmk_extranonce(blktemplate_t *tmpl, void *vout, unsigned int workid, siz
return true;
}
- if (!_blkmk_append_cb(tmpl, vout, &workid, sizeof(workid)))
+ if (!_blkmk_append_cb(tmpl, vout, &workid, sizeof(workid), NULL))
return false;
*offs += insz + sizeof(workid);
@@ -212,6 +302,28 @@ bool _blkmk_extranonce(blktemplate_t *tmpl, void *vout, unsigned int workid, siz
return true;
}
+static
+void blkmk_set_times(blktemplate_t *tmpl, void * const out_hdrbuf, const time_t usetime, int16_t * const out_expire, const bool can_roll_ntime)
+{
+ double time_passed = difftime(usetime, tmpl->_time_rcvd);
+ blktime_t timehdr = tmpl->curtime + time_passed;
+ if (timehdr > tmpl->maxtime)
+ timehdr = tmpl->maxtime;
+ my_htole32(out_hdrbuf, timehdr);
+ if (out_expire)
+ {
+ *out_expire = tmpl->expires - time_passed - 1;
+
+ if (can_roll_ntime)
+ {
+ // If the caller can roll the time header, we need to expire before reaching the maxtime
+ int16_t maxtime_expire_limit = (tmpl->maxtime - timehdr) + 1;
+ if (*out_expire > maxtime_expire_limit)
+ *out_expire = maxtime_expire_limit;
+ }
+ }
+}
+
size_t blkmk_get_data(blktemplate_t *tmpl, void *buf, size_t bufsz, time_t usetime, int16_t *out_expire, unsigned int *out_dataid) {
if (!(blkmk_time_left(tmpl, usetime) && blkmk_work_left(tmpl) && tmpl->cbtxn))
return 0;
@@ -231,12 +343,8 @@ size_t blkmk_get_data(blktemplate_t *tmpl, void *buf, size_t bufsz, time_t useti
if (!build_merkle_root(&cbuf[36], tmpl, cbtxndata, cbtxndatasz))
return 0;
- blktime_t timehdr = tmpl->curtime + difftime(usetime, tmpl->_time_rcvd);
- if (timehdr > tmpl->maxtime)
- timehdr = tmpl->maxtime;
- my_htole32(&cbuf[68], timehdr);
+ blkmk_set_times(tmpl, &cbuf[68], usetime, out_expire, false);
memcpy(&cbuf[72], &tmpl->diffbits, 4);
- // TODO: set *out_expire if provided
// TEMPORARY HACK:
memcpy(tmpl->_mrklroot, &cbuf[36], 32);
@@ -244,6 +352,55 @@ size_t blkmk_get_data(blktemplate_t *tmpl, void *buf, size_t bufsz, time_t useti
return 76;
}
+bool blkmk_get_mdata(blktemplate_t * const tmpl, void * const buf, const size_t bufsz, const time_t usetime, int16_t * const out_expire, void * const _out_cbtxn, size_t * const out_cbtxnsz, size_t * const cbextranonceoffset, int * const out_branchcount, void * const _out_branches, size_t extranoncesz, const bool can_roll_ntime)
+{
+ if (!(true
+ && blkmk_time_left(tmpl, usetime)
+ && tmpl->cbtxn
+ && blkmk_build_merkle_branches(tmpl)
+ && bufsz >= 76
+ ))
+ return false;
+
+ if (extranoncesz == sizeof(unsigned int))
+ // Avoid overlapping with blkmk_get_data use
+ ++extranoncesz;
+
+ void ** const out_branches = _out_branches;
+ void ** const out_cbtxn = _out_cbtxn;
+ unsigned char *cbuf = buf;
+
+ my_htole32(&cbuf[0], tmpl->version);
+ memcpy(&cbuf[4], &tmpl->prevblk, 32);
+
+ *out_cbtxnsz = tmpl->cbtxn->datasz + extranoncesz;
+ *out_cbtxn = malloc(*out_cbtxnsz);
+ if (!*out_cbtxn)
+ return false;
+ unsigned char dummy[extranoncesz];
+ memset(dummy, 0, extranoncesz);
+ if (!_blkmk_append_cb(tmpl, *out_cbtxn, dummy, extranoncesz, cbextranonceoffset))
+ {
+ free(*out_cbtxn);
+ return false;
+ }
+
+ blkmk_set_times(tmpl, &cbuf[68], usetime, out_expire, can_roll_ntime);
+ memcpy(&cbuf[72], &tmpl->diffbits, 4);
+
+ *out_branchcount = tmpl->_mrklbranchcount;
+ const size_t branches_bytesz = (sizeof(libblkmaker_hash_t) * tmpl->_mrklbranchcount);
+ *out_branches = malloc(branches_bytesz);
+ if (!*out_branches)
+ {
+ free(*out_cbtxn);
+ return false;
+ }
+ memcpy(*out_branches, tmpl->_mrklbranch, branches_bytesz);
+
+ return true;
+}
+
blktime_diff_t blkmk_time_left(const blktemplate_t *tmpl, time_t nowtime) {
double age = difftime(nowtime, tmpl->_time_rcvd);
if (age >= tmpl->expires)
diff --git a/blkmaker.h b/blkmaker.h
index 83b6025..4997ade 100644
--- a/blkmaker.h
+++ b/blkmaker.h
@@ -7,16 +7,19 @@
#include <blktemplate.h>
-#define BLKMAKER_VERSION (4L)
+#define BLKMAKER_VERSION (5L)
#define BLKMAKER_MAX_BLOCK_VERSION (2)
extern bool (*blkmk_sha256_impl)(void *hash_out, const void *data, size_t datasz);
extern uint64_t blkmk_init_generation(blktemplate_t *, void *script, size_t scriptsz);
extern uint64_t blkmk_init_generation2(blktemplate_t *, void *script, size_t scriptsz, bool *out_newcb);
+extern uint64_t blkmk_init_generation3(blktemplate_t *, const void *script, size_t scriptsz, bool *inout_newcb);
extern ssize_t blkmk_append_coinbase_safe(blktemplate_t *, const void *append, size_t appendsz);
+extern ssize_t blkmk_append_coinbase_safe2(blktemplate_t *, const void *append, size_t appendsz, int extranoncesz, bool merkle_only);
extern bool _blkmk_extranonce(blktemplate_t *tmpl, void *vout, unsigned int workid, size_t *offs);
extern size_t blkmk_get_data(blktemplate_t *, void *buf, size_t bufsz, time_t usetime, int16_t *out_expire, unsigned int *out_dataid);
+extern bool blkmk_get_mdata(blktemplate_t *, void *buf, size_t bufsz, time_t usetime, int16_t *out_expire, void *out_cbtxn, size_t *out_cbtxnsz, size_t *cbextranonceoffset, int *out_branchcount, void *out_branches, size_t extranoncesz, bool can_roll_ntime);
extern blktime_diff_t blkmk_time_left(const blktemplate_t *, time_t nowtime);
extern unsigned long blkmk_work_left(const blktemplate_t *);
#define BLKMK_UNLIMITED_WORK_COUNT ULONG_MAX
diff --git a/blkmaker_jansson.c b/blkmaker_jansson.c
index dab5f55..2144846 100644
--- a/blkmaker_jansson.c
+++ b/blkmaker_jansson.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2013 Luke Dashjr
+ * Copyright 2012-2014 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.
@@ -130,6 +130,8 @@ err:
tmpl->skey = true; \
} while(0)
+static void my_flip(void *, size_t);
+
static
const char *parse_txn(struct blktxn_t *txn, json_t *txnj) {
json_t *vv;
@@ -146,12 +148,14 @@ const char *parse_txn(struct blktxn_t *txn, json_t *txnj) {
if ((vv = json_object_get(txnj, "hash")) && json_is_string(vv))
{
hexdata = json_string_value(vv);
- txn->hash = malloc(sizeof(*txn->hash));
- if (!my_hex2bin(*txn->hash, hexdata, sizeof(*txn->hash)))
+ txn->hash_ = malloc(sizeof(*txn->hash_));
+ if (!my_hex2bin(*txn->hash_, hexdata, sizeof(*txn->hash_)))
{
- free(txn->hash);
- txn->hash = NULL;
+ free(txn->hash_);
+ txn->hash_ = NULL;
}
+ else
+ my_flip(*txn->hash_, sizeof(*txn->hash_));
}
// TODO: dependcount/depends, fee, required, sigops
@@ -284,7 +288,8 @@ static
json_t *_blkmk_submit_jansson(blktemplate_t *tmpl, const unsigned char *data, unsigned int dataid, blknonce_t nonce, bool foreign) {
unsigned char blk[80 + 8 + 1000000];
memcpy(blk, data, 76);
- *(uint32_t*)(&blk[76]) = htonl(nonce);
+ nonce = htonl(nonce);
+ memcpy(&blk[76], &nonce, 4);
size_t offs = 80;
if (foreign || (!(tmpl->mutations & BMAb_TRUNCATE && !dataid)))
diff --git a/blktemplate.c b/blktemplate.c
index ea4c87d..83d8292 100644
--- a/blktemplate.c
+++ b/blktemplate.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 Luke Dashjr
+ * Copyright 2012-2013 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.
@@ -93,12 +93,13 @@ bool blktmpl_get_submitold(blktemplate_t *tmpl) {
return tmpl->submitold;
}
-static
-void blktxn_free(struct blktxn_t *bt) {
+void _blktxn_free(struct blktxn_t *bt) {
free(bt->data);
free(bt->hash);
+ free(bt->hash_);
free(bt->depends);
}
+#define blktxn_free _blktxn_free
void blktmpl_free(blktemplate_t *tmpl) {
for (unsigned long i = 0; i < tmpl->txncount; ++i)
@@ -109,6 +110,7 @@ void blktmpl_free(blktemplate_t *tmpl) {
blktxn_free(tmpl->cbtxn);
free(tmpl->cbtxn);
}
+ free(tmpl->_mrklbranch);
// TODO: maybe free auxnames[0..n]? auxdata too
free(tmpl->auxnames);
free(tmpl->auxdata);
diff --git a/blktemplate.h b/blktemplate.h
index e9747b7..8b832c5 100644
--- a/blktemplate.h
+++ b/blktemplate.h
@@ -23,6 +23,7 @@ typedef uint32_t blknonce_t;
struct blktxn_t {
unsigned char *data;
size_t datasz;
+ // NOTE: The byte order of hash is backward; use hash_ instead
txnhash_t *hash;
signed long dependcount;
@@ -31,6 +32,8 @@ struct blktxn_t {
uint64_t fee;
bool required;
int16_t sigops;
+
+ txnhash_t *hash_;
};
// BIP 23: Long Polling
@@ -117,6 +120,8 @@ typedef struct {
blknonce_t maxnonce;
// TEMPORARY HACK
+ libblkmaker_hash_t *_mrklbranch;
+ int _mrklbranchcount;
libblkmaker_hash_t _mrklroot;
unsigned int next_dataid;
} blktemplate_t;
diff --git a/configure.ac b/configure.ac
index 8102143..bfc5d1c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-dnl * Copyright 2012-2013 Luke Dashjr
+dnl * Copyright 2012-2014 Luke Dashjr
dnl *
dnl * This program is free software; you can redistribute it and/or modify it
dnl * under the terms of the standard MIT license. See COPYING for more details.
@@ -11,14 +11,15 @@ AC_INIT(
[http://gitorious.org/bitcoin/libblkmaker])
AC_CONFIG_AUX_DIR([.])
AC_PREREQ([2.59])
-AM_INIT_AUTOMAKE([1.10 -Wall dist-bzip2])
+AM_INIT_AUTOMAKE([1.10 -Wall dist-bzip2 foreign])
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
AC_PROG_CC_C99
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
LT_INIT([disable-static])
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
-AC_SUBST([LIBBLKMAKER_SO_VERSION], [4:1:4])
+AC_SUBST([LIBBLKMAKER_SO_VERSION], [5:0:5])
AC_SUBST([LIBBLKMAKER_API_VERSION], [0.1])
AC_CONFIG_FILES([Makefile
diff --git a/private.h b/private.h
index 02a298b..f0e437a 100644
--- a/private.h
+++ b/private.h
@@ -7,6 +7,9 @@
// blkmaker.c
extern bool _blkmk_dblsha256(void *hash, const void *data, size_t datasz);
+// blktemplate.c
+extern void _blktxn_free(struct blktxn_t *);
+
// hex.c
extern void _blkmk_bin2hex(char *out, const void *data, size_t datasz);
extern bool _blkmk_hex2bin(void *o, const char *x, size_t len);
@@ -15,4 +18,16 @@ extern bool _blkmk_hex2bin(void *o, const char *x, size_t len);
extern bool _blkmk_b58tobin(void *bin, size_t binsz, const char *b58, size_t b58sz);
extern int _blkmk_b58check(void *bin, size_t binsz, const char *b58);
+// inline
+
+// NOTE: This must return 0 for 0
+static inline
+int blkmk_flsl(unsigned long n)
+{
+ int i;
+ for (i = 0; n; ++i)
+ n >>= 1;
+ return i;
+}
+
#endif
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-bitcoin/libblkmaker.git
More information about the Pkg-bitcoin-commits
mailing list