diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 109b55a..a3cb1af 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -96,7 +96,7 @@ jobs: platform: linux_amd64 env: - TEST_VERSION: '0.0.3-alpha.4' + TEST_VERSION: '0.0.4-alpha.pr14.5' TEST_REPO: 'stringintech/kernel-bindings-tests' TEST_DIR: '.conformance-tests' diff --git a/native/osx-x64/libbitcoinkernel.dylib b/native/osx-x64/libbitcoinkernel.dylib index 8e7369f..156a823 100755 Binary files a/native/osx-x64/libbitcoinkernel.dylib and b/native/osx-x64/libbitcoinkernel.dylib differ diff --git a/src/BitcoinKernel.Interop/Enums/BlockCheckFlags.cs b/src/BitcoinKernel.Interop/Enums/BlockCheckFlags.cs new file mode 100644 index 0000000..c501ceb --- /dev/null +++ b/src/BitcoinKernel.Interop/Enums/BlockCheckFlags.cs @@ -0,0 +1,31 @@ +namespace BitcoinKernel.Interop.Enums; + +/// +/// Flags controlling optional context-free block checks performed by +/// btck_block_check. The base checks (size limits, coinbase structure, +/// transaction checks, sigop limits) always run; these flags toggle the +/// optional proof-of-work and merkle-root checks. +/// +[Flags] +public enum BlockCheckFlags : uint +{ + /// + /// Run the base context-free block checks only. + /// + Base = 0, + + /// + /// Run CheckProofOfWork via CheckBlockHeader. + /// + Pow = 1U << 0, + + /// + /// Verify merkle root (and mutation detection). + /// + Merkle = 1U << 1, + + /// + /// Enable all optional context-free block checks. + /// + All = Pow | Merkle +} diff --git a/src/BitcoinKernel.Interop/Enums/TxValidationResult.cs b/src/BitcoinKernel.Interop/Enums/TxValidationResult.cs new file mode 100644 index 0000000..88122cd --- /dev/null +++ b/src/BitcoinKernel.Interop/Enums/TxValidationResult.cs @@ -0,0 +1,72 @@ +namespace BitcoinKernel.Interop.Enums; + +/// +/// A granular "reason" why a transaction was invalid. +/// +public enum TxValidationResult : uint +{ + /// + /// Initial value. Tx has not yet been rejected. + /// + UNSET = 0, + + /// + /// Invalid by consensus rules. + /// + CONSENSUS = 1, + + /// + /// Inputs (covered by txid) failed policy rules. + /// + INPUTS_NOT_STANDARD = 2, + + /// + /// Otherwise didn't meet local policy rules. + /// + NOT_STANDARD = 3, + + /// + /// Transaction was missing some of its inputs. + /// + MISSING_INPUTS = 4, + + /// + /// Transaction spends a coinbase too early, or violates locktime/sequence locks. + /// + PREMATURE_SPEND = 5, + + /// + /// Witness may have been malleated or is prior to SegWit activation. + /// + WITNESS_MUTATED = 6, + + /// + /// Transaction is missing a witness. + /// + WITNESS_STRIPPED = 7, + + /// + /// Tx already in mempool or conflicts with a tx in the chain. + /// + CONFLICT = 8, + + /// + /// Violated mempool's fee/size/descendant/RBF/etc limits. + /// + MEMPOOL_POLICY = 9, + + /// + /// This node does not have a mempool so can't validate the transaction. + /// + NO_MEMPOOL = 10, + + /// + /// Fails some policy, but might be acceptable if submitted in a (different) package. + /// + RECONSIDERABLE = 11, + + /// + /// Transaction was not validated because package failed. + /// + UNKNOWN = 12 +} diff --git a/src/BitcoinKernel.Interop/NativeMethods.cs b/src/BitcoinKernel.Interop/NativeMethods.cs index 1b5c770..e81d498 100644 --- a/src/BitcoinKernel.Interop/NativeMethods.cs +++ b/src/BitcoinKernel.Interop/NativeMethods.cs @@ -96,6 +96,13 @@ static NativeMethods() [DllImport(LibName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "btck_chain_parameters_destroy")] public static extern void ChainParametersDestroy(IntPtr chain_params); + /// + /// Gets the consensus parameters from chain parameters. The returned pointer + /// is unowned and only valid for the lifetime of the chain parameters. + /// + [DllImport(LibName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "btck_chain_parameters_get_consensus_params")] + public static extern IntPtr ChainParametersGetConsensusParams(IntPtr chain_parameters); + #endregion #region Chainstate Manager @@ -320,6 +327,26 @@ public static extern int BlockToBytes( [DllImport(LibName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "btck_block_get_transaction_at")] public static extern IntPtr BlockGetTransactionAt(IntPtr block, nuint index); + /// + /// Returns the ancestor of a block tree entry at the given height. + /// + [DllImport(LibName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "btck_block_tree_entry_get_ancestor")] + public static extern IntPtr BlockTreeEntryGetAncestor(IntPtr block_tree_entry, int height); + + /// + /// Performs context-free validation checks on a block. + /// Runs base checks (size, coinbase, tx, sigops) plus optional POW and + /// merkle-root checks controlled by . The + /// validation_state is updated in-place. + /// Returns 1 if the block passed the checks, 0 otherwise. + /// + [DllImport(LibName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "btck_block_check")] + public static extern int BlockCheck( + IntPtr block, + IntPtr consensus_params, + BlockCheckFlags flags, + IntPtr validation_state); + #endregion #region BlockHash Operations @@ -409,6 +436,15 @@ public static extern IntPtr BlockHeaderCreate( [DllImport(LibName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "btck_block_header_destroy")] public static extern void BlockHeaderDestroy(IntPtr header); + /// + /// Serializes a block header to 80 bytes. + /// Returns 0 on success. + /// + [DllImport(LibName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "btck_block_header_to_bytes")] + public static extern int BlockHeaderToBytes( + IntPtr header, + [MarshalAs(UnmanagedType.LPArray, SizeConst = 80)] byte[] output); + #endregion #region Chain Operations @@ -519,6 +555,20 @@ public static extern int TransactionToBytes( [DllImport(LibName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "btck_transaction_output_destroy")] public static extern void TransactionOutputDestroy(IntPtr output); + /// + /// Gets the nLockTime value of a transaction. + /// + [DllImport(LibName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "btck_transaction_get_locktime")] + public static extern uint TransactionGetLocktime(IntPtr transaction); + + /// + /// Runs context-free consensus validation on a transaction. + /// The validation_state is reset on entry and updated in-place. + /// Returns 1 if valid, 0 if invalid. + /// + [DllImport(LibName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "btck_transaction_check")] + public static extern int TransactionCheck(IntPtr tx, IntPtr validation_state); + #endregion #region PrecomputedTransactionData Operations @@ -867,6 +917,12 @@ public static extern IntPtr TransactionSpentOutputsGetCoinAt( [DllImport(LibName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "btck_transaction_input_destroy")] public static extern void TransactionInputDestroy(IntPtr transaction_input); + /// + /// Gets the nSequence value of a transaction input. + /// + [DllImport(LibName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "btck_transaction_input_get_sequence")] + public static extern uint TransactionInputGetSequence(IntPtr transaction_input); + #endregion #region TransactionOutPoint Operations @@ -897,4 +953,33 @@ public static extern IntPtr TransactionSpentOutputsGetCoinAt( #endregion + #region Tx Validation State + + /// + /// Creates a new transaction validation state. + /// + [DllImport(LibName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "btck_tx_validation_state_create")] + public static extern IntPtr TxValidationStateCreate(); + + /// + /// Gets the validation mode from a transaction validation state. + /// + [DllImport(LibName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "btck_tx_validation_state_get_validation_mode")] + public static extern ValidationMode TxValidationStateGetValidationMode(IntPtr validation_state); + + /// + /// Gets the transaction validation result from a transaction validation state. + /// + [DllImport(LibName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "btck_tx_validation_state_get_tx_validation_result")] + public static extern TxValidationResult TxValidationStateGetTxValidationResult(IntPtr validation_state); + + /// + /// Destroys a transaction validation state. + /// + [DllImport(LibName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "btck_tx_validation_state_destroy")] + public static extern void TxValidationStateDestroy(IntPtr validation_state); + + #endregion + + } diff --git a/tools/kernel-bindings-test-handler/Protocol/Response.cs b/tools/kernel-bindings-test-handler/Protocol/Response.cs index 358d641..768373c 100644 --- a/tools/kernel-bindings-test-handler/Protocol/Response.cs +++ b/tools/kernel-bindings-test-handler/Protocol/Response.cs @@ -8,7 +8,7 @@ namespace BitcoinKernel.TestHandler.Protocol; /// public class Response { - [JsonPropertyName("id")] + [JsonIgnore] public string Id { get; set; } = string.Empty; [JsonPropertyName("result")]