[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