* pom.xml now builds JavaDoc, sources and test JARs
* more descriptive output from test classes to aid debugging
* actually add/collate AT-generated transactions to test blockchain for analysis
* test block period changed from 10 minutes to 1 minute
* 'quiet' logger aded that doesn't emit DEBUG log entries
SLP_DAT addr: fixed to work as advertised
SLP_VAL value: sleeps for <value> blocks
SHL_VAL addr value: left-shifts the contents of addr by value bits
SHR_VAL addr value: right-shifts the contents of addr by value bits
EXT_FUN_VAL func value: pass a value to a function instead of fetching via addr
This allows new functions GET_A_DAT to take data segment address,
instead of convoluted GET_A_IND which requires an address stored in the data segment (like a pointer).
New FunctionCodes:
GET_A_DAT, GET_B_DAT, SET_A_DAT, SET_B_DAT (see above)
UNSIGNED_COMPARE_A_WITH_B, SIGNED_COMPARE_A_WITH_B
Add branch offset bounds checking to OpCode.calcOffset method (throws if out of bounds). Added test to cover.
Tidied up JavaDoc, which is now also generated by pom.xml!
Added JavaDoc comments to OpCodeParam enum entries.
Corrected some inaccurate descriptions.
Converted obsolete <tt> tags to <code>.
Fixed some invalid HTML, converted raw characters like &, <, >, etc. to HTML entites like &, > and →
Bumped version to 1.4.0
The test "functionData.value2 > state.numDataPages" was incorrect
because value2 contains a a BYTE count, so could be up to 8 times
bigger than state.numDataPages!
Reverted back to looser check of "functionData.value2 > Integer.MAX_VALUE"
We now use a logger factory, which means loggers can be created
per class.
This allows use of 'wrapped' Apache log4j2 loggers with the added
benefit of more accurate class/line-number reporting.
OpCode.compile(...) takes varargs as necessary, and returns byte[].
It will complain if the number of args is incorrect, or if any arg
cannot be coerced into the correct form (byte/int/short/long).
It will also complain if you try to use a branch offset that is too
big to fit into byte.
Two-pass compilation support added with OpCode.calcOffset(ByteBuffer, Integer)
where Integer is null during the first pass, but also set to ByteBuffer.position()
during first pass, so proper value can be calculated during second pass.
MachineState.disassemble() changed into a public static method,
requiring far less effort to call.
Checking of branch target bounds now done by each OpCode as
doing it in OpCodeParam wasn't reliable as PC wasn't available.
Yet more visibility tightening.
Improved comments.
Yet more tests.
Added unit test to cover branching to beyond end of code segment.
Added unit test to cover branching to before start of code segment.
Added very naive fuzzy disassembly test to see how it handles random, invalid code.
Refactored data address checking in FunctionCode.postCheckExecute() methods to
single FunctionCode.checkDataAddress method. New method includes FunctionCode's name
when throwing due to out-of-bounds address.
Tidied narrowing conversions by replacing literal 0x7fffffffL with Integer.MAX_VALUE.
Tightened OpCode methods visiblity from public to protected.
Added branch target checking to OpCode.executeBranchConditional but maybe this is
already covered by call to Utils.getCodeOffset() when assembling params in Opcode.execute().
Improved message in Utils.getCodeOffset() anyway.
Moved unit tests to org.ciyam.at package.
Moved unit test support classes from 'common' to org.ciyam.at.test.
NOTE: this constructor's args have changed from:
public MachineState(byte[] creationBytes)
to:
public MachineState(API api, byte[] creationBytes)
The bug was miscalculating 'expectedLength'.
Added unit test to cover above.
Also added unit test to cover branching backwards.
Bumped version to 1.3.1 and also fixed pom.xml so it's possible
to call 'mvn clean package' from command line without errors.
Rolled the superior blockchain simulating parts from ACCTAPI into
TestAPI.
Tried to replace literal test values with named constants from TestAPI
class, or derived values.
Added some more opcode tests to cover more cases.
Renamed some functions of the form "put something ... in A" to
"put something .. into A" to help distinguish them from
"get ... based on something in A".
Added {GET,SET}_[AB]_IND functions as an addition to the long-winded
GET_A1..A4, SET_B1..B4.
Added more function code tests and separated those tests out into 3
different test classes for manageability.
Possible logic error in PAY_TO_ADDRESS_IN_B and PAY_PREVIOUS_TO_ADDRESS_IN_B
but needs testing!
Improved comments.
Conversion to big-endian to allow reuse of hash output without
having to swap endian. e.g. saving output of HASH160 into data
segment, and then hashing more of data segment to produce P2SH address.
Also changed hashing functions to fetch data start address and data
byte length from data segment, rather than loading values into A.
Tidied up some tests.
Remove obsolete ACCT test.
Before, hashing functions (e.g. MD5_A_INTO_B) would hash immediate
data stored in A, putting the result into B.
Also, that hash function would only hash the same number of bits as
the hash output. For example, MD5_A_INTO_B would only hash the
16 bytes in A1 & A2.
Now, hash functions use data-page offset stored in A1 and byte-length
stored in A2.
Renamed HASH160 to RMD160 and created new HASH160 which performs
Bitcoin's double hash of RMD160(SHA256(data)).
Refactored & added tests to cover.
API:
Added sample AT-emitted transaction types (payment/message).
Maximum number of steps per execution round no longer hard-coded.
API.putTransactionAfterTimestampInA() sets A to zero if no more transactions.
API.putMessageFromTransactionInAIntoB sets B to zero if not a message transaction.
Added some convenience methods.
MachineState:
Added support for minimum activation amount.
Added static method for packing AT into "creation bytes".
No need to store unchanging code in per-height AT state data.
Added support for multiple blockchains to "Timestamp".
General improvements based on Sonarlint suggestions.
General improvements to comments.
Replaced deprecated Byte/Short/Integer/Long constructor call with corresponding .valueOf() call.
Replaced some string concatenations with StringBuilder.
Moved Java-related .gitignore from root to /Java/
Removed .classpath and .project, and added same to .gitignore
Added info on how to add CIYAM AT JAR to other projects.
Updated pom.xml:
Bumped version to 1.2
Bumped Java version from 1.8 to 11
Bumped BouncyCastle from 1.60 to 1.64
Added more tests.
Two new API calls:
getOpCodeSteps(OpCode) : int
getFeePerStep() : long
This allows API to determine cost per "step" and charge more for (say) function opcodes.
MachineState knows the balance at the end of each execution round,
so now AT's previousBalance is managed by MachineState and added to serialized data.
API calls payCurrentBalanceToB and payPreviousBalanceToB are absorbed into payAmountToB,
and amounts passed are calculated by FunctionCode instead.
Added API call onFinished(long amount, MachineState state) for when AT has finished
so API can return remaining funds (amount) to creator.
Added API call isFirstOpCodeAfterSleeping() : boolean to replace dodgy test of
state.getSteps() == 0 in getRandomUsingTransactionInA().
The API call getCurrentBalance is now used by MachineState to find out AT's balance
at the beginning of execution round. After this, MachineState manages the balance until
the end of execution, whereby the caller can find out the new balance from MachineState.
Corrected some code in FunctionCode to get current balance from MachineState instead in
light of above. (Ditto previousBalance).
Added MAX_STEPS to MachineState to ATs can be made to sleep if they execute too many
steps in one execution round.
Added some pre-execution checks to MachineState.execute() to prevent execution in some
cases, like already finished, or not enough balance to un-freeze, or not reached
required block while sleeping, etc.
Unit tests pass, but there are no test for new steps/fee code yet!
API is now an abstract class instead of an Interface. This is to
allow protected methods that give access to package-scoped methods
and variables inside MachineState.
MachineState now supports a different set of constants based on AT
version.
MachineState's methods and variables have had their scopes tightened
up and getters/setters added where appropriate.
MachineState.parseHeader() inlined into the constructor that calls it
so it can set public final variables.
Some reordering and additional comments in MachineState.
OpCode enum entries refactored so that:
a) variables provided via MachineState "state" are not explicitly
passed as well
b) args to each opcode are pre-fetched from the codeByteBuffer before
calling and only need to be cast before use. this comes almost
"for free" thanks to OpCodeParam.fetch
Calling functions from OpCode now cleaner as there's no write-access
to programCounter, only changing codeByteBuffer's position.
Also in OpCode, state.getProgramCounter() now provides a consistent
before-opcode position for branches, jumps, etc.
Lots of repeated code refactored out of unit tests into ExecutableTest
class. ExecutableTest also provides helper methods for examining
post-execution data values, stack positions and entries.