mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-15 02:26:40 +00:00

* [NOD-828] Reimplement FFLDB (#663) * [NOD-828] Create the database2 package that will some day replace the database package. * [NOD-828] Implement a "bucket" key mechanism. * [NOD-828] Move bucket.go into the ffldb2 package. * [NOD-828] Delete the un-interfaced ffldb package from database2, since we aren't going to be using it anyway. * [NOD-828] Copy over + fixup flat file structs from the old ffldb. * [NOD-828] Implement flatFilePath. * [NOD-828] Implement flatFileStore.write(). * [NOD-828] Implement flatFileStore.read(). * [NOD-828] Implement flatFileStore.rollback(). * [NOD-828] Sync the file to disk at the end of write(). * [NOD-828] Extract crc32ByteOrder to a separate variable. * [NOD-828] Add a sanity test. * [NOD-828] Remove context-unrelated methods from the Database interface. * [NOD-828] Create an ffldb object. Simply work against a context. * [NOD-828] Open the new database on start. * [NOD-828] Create the leveldb package. * [NOD-828] Implement opening/closing leveldb. * [NOD-828] Implement get/put out of/into leveldb. * [NOD-828] Implement transactions and make them implement a generic database interface. * [NOD-828] Write sanity tests for leveldb with and without transactions. * [NOD-828] Add another case to the transaction sanity test. * [NOD-828] Implement AppendBlock/RetrieveBlock. * [NOD-828] Refactor so that concepts such as "block" and "metadata" don't leak into the database package. * [NOD-828] Add RollbackFlatData to the database interface. * [NOD-828] Remove anything from dbaccess that I'm not planning to implement as part of this ticket. * [NOD-828] Implement StoreBlock. * [NOD-828] Implement FetchBlock. * [NOD-828] Implement HasBlock. * [NOD-828] Write a sanity test for block insertion. * [NOD-828] Implement CurrentFlatDataLocation. * [NOD-828] Implement storing the current block location. * [NOD-828] Implement initializing/syncing the flat file block store and the "metadata". * [NOD-828] Add InitBlockStore to TestBlockStoreSanity. * [NOD-828] Fix rename errors. * [NOD-828] Fix lint errors in the root database package. * [NOD-828] Fix lint errors in the ffldb.go. * [NOD-828] Fix lint errors in the flatfile/db.go. * [NOD-828] Rename packages in such a way to make the linter happy. * [NOD-828] Finish satisfying the linter. * [NOD-828] Fix doc.go. * [NOD-828] Fix comments in block.go. * [NOD-828] Move dbaccess out of the database package. * [NOD-828] Move opening/closing the database to dbaccess. * [NOD-828] Move the Database interface to the root database package, since it's meant to be generic. * [NOD-828] Make ffldb generic to later support additional databases. * [NOD-828] Make ffldb.Open return DatabaseHandle, since ffldb is no longer exported. * [NOD-828] Fix comments. * [NOD-828] Rename AppendFlatData to AppendToStore and RetrieveFlatData to RetrieveFromStore. * [NOD-828] Make buckets nicer to use. * [NOD-828] Implement cursors that iterate over some bucket. * [NOD-828] Generalize flat-file repairing and move block database repairing into ffldb. * [NOD-828] Write a test making sure that flat file repair works. * [NOD-828] Properly close the database in TestRepairFlatFiles. * [NOD-828] Add a comment warning against putting and getting the same data within the same transaction. * [NOD-828] Fix the flatFilesBucket description. * [NOD-828] Remove superfluous whitespace. * [NOD-828] Fix the ffldb description. * [NOD-828] Rename Database to DataAccessor and rename Handle to Database. * [NOD-828] Make Get return nil if the value doesn't exist. * [NOD-828] Attempt to close leveldb even if closing ffdb failed. * [NOD-828] Fix a bug where the wrong location would be written to the current store location bucket. * [NOD-828] Fix not updating the store location in ffldb transactions. * [NOD-828] Make scanFlatFiles return an error if os.Stat fails for any reason other than file-not-found. * [NOD-828] Update the README and doc.go. * [NOD-828] Simplify Bucket.Path(). * [NOD-828] Since LevelDBCursor satisfied the database2.Cursor interface, use it directly. * [NOD-828] Combine two lines into one. * [NOD-828] Combine another two lines into one. * [NOD-828] Move a misplaced comment. * [NOD-828] Use Wrapf instead of Errorf where appropriate. * [NOD-828] Fix a comment. * [NOD-828] Fix a comment. * [NOD-828] Fix Wrapf calls. * [NOD-828] Fix comments. * [NOD-828] Remove superfluous whitespace. * [NOD-828] Add a comment explaining the use of batches and snapshots. * [NOD-828] Implement RollbackUnlessClosed(). * [NOD-828] Return both errors in StoreBlock rollback. * [NOD-828] Move rollback-on-error logic into ffldb. Remove CurrentStoreLocation and RollbackStore from DataAccessor. * [NOD-828] Make bucket a type alias instead of a struct. * [NOD-828] Fix a typo. * [NOD-828] Use copy instead of append in Bucket. * [NOD-828] Extract flatFileLocationSerializedSize to a const. * [NOD-828] Debugf -> Warnf in rollback.go. * [NOD-828] Fix a comment. * [NOD-828] Fix a comment. * [NOD-828] Remove data length from flat file data format. * [NOD-828] Rearrange TestLevelDBTransactionSanity a bit. * [NOD-828] Add stack traces to all errors that come out of library functions. * [NOD-828] Return errors from rollback(). * [NOD-828] Remove an irrelevant comment. * [NOD-828] Remove redundant whitespace. * [NOD-828] Handle nil in FetchBlock. * [NOD-828] Move the explanation about batches and snapshots to the LevelDBTransaction struct. * Revert "[NOD-828] Make bucket a type alias instead of a struct." This reverts commit 1fd39652 * [NOD-828] Fix revert errors. * Revert "[NOD-828] Remove data length from flat file data format." This reverts commit ef408e32 * [NOD-862] Move Cursor() into the DataAccessor interface. * [NOD-828] Add Delete to DataAccessor. * [NOD-828] Fix a couple of places that erroneously referenced blocks. * [NOD-828] Add a comment on top of flatFileLocationSerializedSize. * [NOD-828] Add Seek to Cursor. * [NOD-828] Add First to Cursor. * [NOD-828] Rename db to accessor in Context. * [NOD-828] Make Get/Fetch calls return a boolean to indicate whether the requested item was found. * [NOD-828] Name the output parameters of all Get functions. * [NOD-828] Make RetrieveFromStore return whether the data was found. * [NOD-887] Add a couple of QoL features to Cursor (#674) * [NOD-887] Changed First to not return an error. * [NOD-887] Fix merge error. * [NOD-887] Make Cursor.Key not return the entire key path. * [NOD-888] Add RollbackUnlessClosed to Context (#676) * [NOD-888] Add RollbackUnlessClosed to Context. * [NOD-888] Fix copy+paste error. * [NOD-889] Instead of returning a boolean for not-found, return an error (#677) * [NOD-889] Instead of returning a boolean for not-found, return an error. * [NOD-889] Wrapped ErrNotFound for Get calls with nicer error messages. * [NOD-889] Fix format. * [NOD-889] Fix double space in a comment. * [NOD-889] Add IsNotFoundError to dbaccess. * [NOD-862] Replace calls to Tx.StoreBlock, Tx.HasBlock, Tx.FetchBlock with appropriate calls in dbaccess (#672) * [NOD-828] Create the database2 package that will some day replace the database package. * [NOD-828] Implement a "bucket" key mechanism. * [NOD-828] Move bucket.go into the ffldb2 package. * [NOD-828] Delete the un-interfaced ffldb package from database2, since we aren't going to be using it anyway. * [NOD-828] Copy over + fixup flat file structs from the old ffldb. * [NOD-828] Implement flatFilePath. * [NOD-828] Implement flatFileStore.write(). * [NOD-828] Implement flatFileStore.read(). * [NOD-828] Implement flatFileStore.rollback(). * [NOD-828] Sync the file to disk at the end of write(). * [NOD-828] Extract crc32ByteOrder to a separate variable. * [NOD-828] Add a sanity test. * [NOD-828] Remove context-unrelated methods from the Database interface. * [NOD-828] Create an ffldb object. Simply work against a context. * [NOD-828] Open the new database on start. * [NOD-828] Create the leveldb package. * [NOD-828] Implement opening/closing leveldb. * [NOD-828] Implement get/put out of/into leveldb. * [NOD-828] Implement transactions and make them implement a generic database interface. * [NOD-828] Write sanity tests for leveldb with and without transactions. * [NOD-828] Add another case to the transaction sanity test. * [NOD-828] Implement AppendBlock/RetrieveBlock. * [NOD-828] Refactor so that concepts such as "block" and "metadata" don't leak into the database package. * [NOD-828] Add RollbackFlatData to the database interface. * [NOD-828] Remove anything from dbaccess that I'm not planning to implement as part of this ticket. * [NOD-828] Implement StoreBlock. * [NOD-828] Implement FetchBlock. * [NOD-828] Implement HasBlock. * [NOD-828] Write a sanity test for block insertion. * [NOD-828] Implement CurrentFlatDataLocation. * [NOD-828] Implement storing the current block location. * [NOD-828] Implement initializing/syncing the flat file block store and the "metadata". * [NOD-828] Add InitBlockStore to TestBlockStoreSanity. * [NOD-828] Fix rename errors. * [NOD-828] Fix lint errors in the root database package. * [NOD-828] Fix lint errors in the ffldb.go. * [NOD-828] Fix lint errors in the flatfile/db.go. * [NOD-828] Rename packages in such a way to make the linter happy. * [NOD-828] Finish satisfying the linter. * [NOD-828] Fix doc.go. * [NOD-828] Fix comments in block.go. * [NOD-828] Move dbaccess out of the database package. * [NOD-828] Move opening/closing the database to dbaccess. * [NOD-828] Move the Database interface to the root database package, since it's meant to be generic. * [NOD-828] Make ffldb generic to later support additional databases. * [NOD-828] Make ffldb.Open return DatabaseHandle, since ffldb is no longer exported. * [NOD-828] Fix comments. * [NOD-828] Rename AppendFlatData to AppendToStore and RetrieveFlatData to RetrieveFromStore. * [NOD-828] Make buckets nicer to use. * [NOD-828] Implement cursors that iterate over some bucket. * [NOD-828] Generalize flat-file repairing and move block database repairing into ffldb. * [NOD-828] Write a test making sure that flat file repair works. * [NOD-828] Properly close the database in TestRepairFlatFiles. * [NOD-828] Add a comment warning against putting and getting the same data within the same transaction. * [NOD-862] Use dbaccess.HasBlock instead of Tx.HasBlock in initDAGState. * [NOD-862] Use dbaccess.StoreBlock instead of dbStoreBlock. * [NOD-862] Use dbaccess.FetchBlock instead of various block fetching mechanisms. * [NOD-828] Fix the flatFilesBucket description. * [NOD-828] Remove superfluous whitespace. * [NOD-828] Fix the ffldb description. * [NOD-828] Rename Database to DataAccessor and rename Handle to Database. * [NOD-828] Make Get return nil if the value doesn't exist. * [NOD-828] Attempt to close leveldb even if closing ffdb failed. * [NOD-828] Fix a bug where the wrong location would be written to the current store location bucket. * [NOD-828] Fix not updating the store location in ffldb transactions. * [NOD-828] Make scanFlatFiles return an error if os.Stat fails for any reason other than file-not-found. * [NOD-828] Update the README and doc.go. * [NOD-828] Simplify Bucket.Path(). * [NOD-828] Since LevelDBCursor satisfied the database2.Cursor interface, use it directly. * [NOD-828] Combine two lines into one. * [NOD-828] Combine another two lines into one. * [NOD-828] Move a misplaced comment. * [NOD-828] Use Wrapf instead of Errorf where appropriate. * [NOD-828] Fix a comment. * [NOD-828] Fix a comment. * [NOD-828] Fix Wrapf calls. * [NOD-828] Fix comments. * [NOD-828] Remove superfluous whitespace. * [NOD-828] Add a comment explaining the use of batches and snapshots. * [NOD-828] Implement RollbackUnlessClosed(). * [NOD-828] Return both errors in StoreBlock rollback. * [NOD-828] Move rollback-on-error logic into ffldb. Remove CurrentStoreLocation and RollbackStore from DataAccessor. * [NOD-828] Make bucket a type alias instead of a struct. * [NOD-828] Fix a typo. * [NOD-828] Use copy instead of append in Bucket. * [NOD-828] Extract flatFileLocationSerializedSize to a const. * [NOD-828] Debugf -> Warnf in rollback.go. * [NOD-828] Fix a comment. * [NOD-828] Fix a comment. * [NOD-828] Remove data length from flat file data format. * [NOD-828] Rearrange TestLevelDBTransactionSanity a bit. * [NOD-828] Add stack traces to all errors that come out of library functions. * [NOD-828] Return errors from rollback(). * [NOD-828] Remove an irrelevant comment. * [NOD-828] Remove redundant whitespace. * [NOD-828] Handle nil in FetchBlock. * [NOD-828] Implement a dbaccess.BlockNode struct. * [NOD-828] Move the explanation about batches and snapshots to the LevelDBTransaction struct. * [NOD-828] Implement toDBBlockNode and fromDBBlockNode. * Revert "[NOD-828] Make bucket a type alias instead of a struct." This reverts commit 1fd39652 * [NOD-828] Fix revert errors. * Revert "[NOD-828] Remove data length from flat file data format." This reverts commit ef408e32 * [NOD-862] Implement storing index blocks. * [NOD-862] Use database transactions where appropriate. * [NOD-862] Fix tests failing on DAGSetup. * [NOD-862] Fix bad make call. * [NOD-862] Fix remaining database opening problems in tests. * [NOD-862] Move Cursor() into the DataAccessor interface. * [NOD-862] Move Cursor() into the DataAccessor interface. * [NOD-862] Iterate over the new block index in dagio. * [NOD-862] Fix block index key. * [NOD-828] Add Delete to DataAccessor. * [NOD-862] Pass byte slices to dbaccess instead of objects. * [NOD-862] Fix errors. * [NOD-862] Fix maybeAcceptBlock not checking block existence. * [NOD-862] Fix TestAcceptanceIndexRecover. * [NOD-862] Add comments to StoreBlockIndex and BlockIndexCursor. * [NOD-828] Fix a couple of places that erroneously referenced blocks. * [NOD-828] Add a comment on top of flatFileLocationSerializedSize. * [NOD-828] Add Seek to Cursor. * [NOD-828] Add First to Cursor. * [NOD-828] Rename db to accessor in Context. * [NOD-828] Make Get/Fetch calls return a boolean to indicate whether the requested item was found. * [NOD-828] Name the output parameters of all Get functions. * [NOD-828] Make RetrieveFromStore return whether the data was found. * [NOD-862] Fix merge errors. * [NOD-862] Fix DAGSetup using bad temp directories. * [NOD-862] Fix TestProcessDelayedBlocks not closing the database properly. * [NOD-862] Fix merge errors. * [NOD-862] Merge flushToDBWithContext and flushToDB. * [NOD-862] Remove TODO. * [NOD-862] Add prefix to the temp dir in DAGSetup. * [NOD-862] Bring back dbFetchBlockByHash. * [NOD-862] Use BlockDAG.BlockByHash in p2p and rpc. * [NOD-862] Use daghash.Hash in dbaccess. * [NOD-862] Add defer to RollbackUnlessClosed after NewTx(). * [NOD-862] Extract dbStoreBlock to a separate function. * [NOD-862] Fix grammar in comment. * [NOD-862] Fix merge errors. * [NOD-867] Migrate database logic in blockdag/dagio.go to dbaccess (#675) * [NOD-828] Create the database2 package that will some day replace the database package. * [NOD-828] Implement a "bucket" key mechanism. * [NOD-828] Move bucket.go into the ffldb2 package. * [NOD-828] Delete the un-interfaced ffldb package from database2, since we aren't going to be using it anyway. * [NOD-828] Copy over + fixup flat file structs from the old ffldb. * [NOD-828] Implement flatFilePath. * [NOD-828] Implement flatFileStore.write(). * [NOD-828] Implement flatFileStore.read(). * [NOD-828] Implement flatFileStore.rollback(). * [NOD-828] Sync the file to disk at the end of write(). * [NOD-828] Extract crc32ByteOrder to a separate variable. * [NOD-828] Add a sanity test. * [NOD-828] Remove context-unrelated methods from the Database interface. * [NOD-828] Create an ffldb object. Simply work against a context. * [NOD-828] Open the new database on start. * [NOD-828] Create the leveldb package. * [NOD-828] Implement opening/closing leveldb. * [NOD-828] Implement get/put out of/into leveldb. * [NOD-828] Implement transactions and make them implement a generic database interface. * [NOD-828] Write sanity tests for leveldb with and without transactions. * [NOD-828] Add another case to the transaction sanity test. * [NOD-828] Implement AppendBlock/RetrieveBlock. * [NOD-828] Refactor so that concepts such as "block" and "metadata" don't leak into the database package. * [NOD-828] Add RollbackFlatData to the database interface. * [NOD-828] Remove anything from dbaccess that I'm not planning to implement as part of this ticket. * [NOD-828] Implement StoreBlock. * [NOD-828] Implement FetchBlock. * [NOD-828] Implement HasBlock. * [NOD-828] Write a sanity test for block insertion. * [NOD-828] Implement CurrentFlatDataLocation. * [NOD-828] Implement storing the current block location. * [NOD-828] Implement initializing/syncing the flat file block store and the "metadata". * [NOD-828] Add InitBlockStore to TestBlockStoreSanity. * [NOD-828] Fix rename errors. * [NOD-828] Fix lint errors in the root database package. * [NOD-828] Fix lint errors in the ffldb.go. * [NOD-828] Fix lint errors in the flatfile/db.go. * [NOD-828] Rename packages in such a way to make the linter happy. * [NOD-828] Finish satisfying the linter. * [NOD-828] Fix doc.go. * [NOD-828] Fix comments in block.go. * [NOD-828] Move dbaccess out of the database package. * [NOD-828] Move opening/closing the database to dbaccess. * [NOD-828] Move the Database interface to the root database package, since it's meant to be generic. * [NOD-828] Make ffldb generic to later support additional databases. * [NOD-828] Make ffldb.Open return DatabaseHandle, since ffldb is no longer exported. * [NOD-828] Fix comments. * [NOD-828] Rename AppendFlatData to AppendToStore and RetrieveFlatData to RetrieveFromStore. * [NOD-828] Make buckets nicer to use. * [NOD-828] Implement cursors that iterate over some bucket. * [NOD-828] Generalize flat-file repairing and move block database repairing into ffldb. * [NOD-828] Write a test making sure that flat file repair works. * [NOD-828] Properly close the database in TestRepairFlatFiles. * [NOD-828] Add a comment warning against putting and getting the same data within the same transaction. * [NOD-862] Use dbaccess.HasBlock instead of Tx.HasBlock in initDAGState. * [NOD-862] Use dbaccess.StoreBlock instead of dbStoreBlock. * [NOD-862] Use dbaccess.FetchBlock instead of various block fetching mechanisms. * [NOD-828] Fix the flatFilesBucket description. * [NOD-828] Remove superfluous whitespace. * [NOD-828] Fix the ffldb description. * [NOD-828] Rename Database to DataAccessor and rename Handle to Database. * [NOD-828] Make Get return nil if the value doesn't exist. * [NOD-828] Attempt to close leveldb even if closing ffdb failed. * [NOD-828] Fix a bug where the wrong location would be written to the current store location bucket. * [NOD-828] Fix not updating the store location in ffldb transactions. * [NOD-828] Make scanFlatFiles return an error if os.Stat fails for any reason other than file-not-found. * [NOD-828] Update the README and doc.go. * [NOD-828] Simplify Bucket.Path(). * [NOD-828] Since LevelDBCursor satisfied the database2.Cursor interface, use it directly. * [NOD-828] Combine two lines into one. * [NOD-828] Combine another two lines into one. * [NOD-828] Move a misplaced comment. * [NOD-828] Use Wrapf instead of Errorf where appropriate. * [NOD-828] Fix a comment. * [NOD-828] Fix a comment. * [NOD-828] Fix Wrapf calls. * [NOD-828] Fix comments. * [NOD-828] Remove superfluous whitespace. * [NOD-828] Add a comment explaining the use of batches and snapshots. * [NOD-828] Implement RollbackUnlessClosed(). * [NOD-828] Return both errors in StoreBlock rollback. * [NOD-828] Move rollback-on-error logic into ffldb. Remove CurrentStoreLocation and RollbackStore from DataAccessor. * [NOD-828] Make bucket a type alias instead of a struct. * [NOD-828] Fix a typo. * [NOD-828] Use copy instead of append in Bucket. * [NOD-828] Extract flatFileLocationSerializedSize to a const. * [NOD-828] Debugf -> Warnf in rollback.go. * [NOD-828] Fix a comment. * [NOD-828] Fix a comment. * [NOD-828] Remove data length from flat file data format. * [NOD-828] Rearrange TestLevelDBTransactionSanity a bit. * [NOD-828] Add stack traces to all errors that come out of library functions. * [NOD-828] Return errors from rollback(). * [NOD-828] Remove an irrelevant comment. * [NOD-828] Remove redundant whitespace. * [NOD-828] Handle nil in FetchBlock. * [NOD-828] Implement a dbaccess.BlockNode struct. * [NOD-828] Move the explanation about batches and snapshots to the LevelDBTransaction struct. * [NOD-828] Implement toDBBlockNode and fromDBBlockNode. * Revert "[NOD-828] Make bucket a type alias instead of a struct." This reverts commit 1fd39652 * [NOD-828] Fix revert errors. * Revert "[NOD-828] Remove data length from flat file data format." This reverts commit ef408e32 * [NOD-862] Implement storing index blocks. * [NOD-862] Use database transactions where appropriate. * [NOD-862] Fix tests failing on DAGSetup. * [NOD-862] Fix bad make call. * [NOD-862] Fix remaining database opening problems in tests. * [NOD-862] Move Cursor() into the DataAccessor interface. * [NOD-862] Move Cursor() into the DataAccessor interface. * [NOD-862] Iterate over the new block index in dagio. * [NOD-862] Fix block index key. * [NOD-828] Add Delete to DataAccessor. * [NOD-862] Pass byte slices to dbaccess instead of objects. * [NOD-862] Fix errors. * [NOD-862] Fix maybeAcceptBlock not checking block existence. * [NOD-862] Fix TestAcceptanceIndexRecover. * [NOD-862] Add comments to StoreBlockIndex and BlockIndexCursor. * [NOD-828] Fix a couple of places that erroneously referenced blocks. * [NOD-828] Add a comment on top of flatFileLocationSerializedSize. * [NOD-828] Add Seek to Cursor. * [NOD-828] Add First to Cursor. * [NOD-828] Rename db to accessor in Context. * [NOD-828] Make Get/Fetch calls return a boolean to indicate whether the requested item was found. * [NOD-828] Name the output parameters of all Get functions. * [NOD-828] Make RetrieveFromStore return whether the data was found. * [NOD-862] Fix merge errors. * [NOD-862] Fix DAGSetup using bad temp directories. * [NOD-862] Fix TestProcessDelayedBlocks not closing the database properly. * [NOD-867] Remove blockIndexBucket from dagio. * [NOD-867] Fix wrong key in StoreIndexBucket. * [NOD-867] Migrate DAG state to dbaccess. * [NOD-867] Remove utxoSetVersionKeyName. * [NOD-862] Fix merge errors. * [NOD-867] Move localSubnetworkID into dagState. * [NOD-867] Fix a comment. * [NOD-867] Remove an unused function. * [NOD-867] Migrate the database's UTXO set to dbaccess. * [NOD-867] Add missing error check. * [NOD-867] Changed First to not return an error. * [NOD-867] Make Cursor.Key not return the entire key path. * [NOD-887] Fix the comment above BlockIndexCursorFrom. * [NOD-862] Merge flushToDBWithContext and flushToDB. * [NOD-862] Remove TODO. * [NOD-862] Add prefix to the temp dir in DAGSetup. * [NOD-862] Bring back dbFetchBlockByHash. * [NOD-862] Use BlockDAG.BlockByHash in p2p and rpc. * [NOD-862] Use daghash.Hash in dbaccess. * [NOD-862] Add defer to RollbackUnlessClosed after NewTx(). * [NOD-862] Extract dbStoreBlock to a separate function. * [NOD-867] Remove TODOs. * [NOD-867] Fix merge errors. * [NOD-867] Fix comments and errors. * [NOD-867] Unexport blockIndexKey. * [NOD-867] Fix merge errors. * [NOD-867] Move a misplaced comment. * [NOD-867] Fix an error message. * [NOD-867] Remove preallocation in initDAGState. * [NOD-866] Migrate database logic in blockdag/indexers package to dbaccess (#682) * [NOD-865] Delete blockidhash.go. * [NOD-865] Remove a lot of no-longer relevant logic from indexers. * [NOD-865] Pass TxContext to ConnectBlock. * [NOD-865] Migrate the acceptance index to dbaccess. * [NOD-865] Fix a block not being sent to ConnectBlock. * [NOD-865] Pass the block's hash instead of the whole block. * [NOD-865] Add forgotten Commit call. * [NOD-865] Add comments. * [NOD-866] Fix a comment. * [NOD-866] Fix a comment. * [NOD-866] Remove pointless indirection in acceptanceindex. * [NOD-866] Fix comment over ForEachHash. * [NOD-866] Rename ClearAcceptanceIndex to DropAcceptanceIndex. * [NOD-866] Explain collecting keys before deleting them. * [NOD-865] Move misc db logic to db access (#681) * [NOD-828] Create the database2 package that will some day replace the database package. * [NOD-828] Implement a "bucket" key mechanism. * [NOD-828] Move bucket.go into the ffldb2 package. * [NOD-828] Delete the un-interfaced ffldb package from database2, since we aren't going to be using it anyway. * [NOD-828] Copy over + fixup flat file structs from the old ffldb. * [NOD-828] Implement flatFilePath. * [NOD-828] Implement flatFileStore.write(). * [NOD-828] Implement flatFileStore.read(). * [NOD-828] Implement flatFileStore.rollback(). * [NOD-828] Sync the file to disk at the end of write(). * [NOD-828] Extract crc32ByteOrder to a separate variable. * [NOD-828] Add a sanity test. * [NOD-828] Remove context-unrelated methods from the Database interface. * [NOD-828] Create an ffldb object. Simply work against a context. * [NOD-828] Open the new database on start. * [NOD-828] Create the leveldb package. * [NOD-828] Implement opening/closing leveldb. * [NOD-828] Implement get/put out of/into leveldb. * [NOD-828] Implement transactions and make them implement a generic database interface. * [NOD-828] Write sanity tests for leveldb with and without transactions. * [NOD-828] Add another case to the transaction sanity test. * [NOD-828] Implement AppendBlock/RetrieveBlock. * [NOD-828] Refactor so that concepts such as "block" and "metadata" don't leak into the database package. * [NOD-828] Add RollbackFlatData to the database interface. * [NOD-828] Remove anything from dbaccess that I'm not planning to implement as part of this ticket. * [NOD-828] Implement StoreBlock. * [NOD-828] Implement FetchBlock. * [NOD-828] Implement HasBlock. * [NOD-828] Write a sanity test for block insertion. * [NOD-828] Implement CurrentFlatDataLocation. * [NOD-828] Implement storing the current block location. * [NOD-828] Implement initializing/syncing the flat file block store and the "metadata". * [NOD-828] Add InitBlockStore to TestBlockStoreSanity. * [NOD-828] Fix rename errors. * [NOD-828] Fix lint errors in the root database package. * [NOD-828] Fix lint errors in the ffldb.go. * [NOD-828] Fix lint errors in the flatfile/db.go. * [NOD-828] Rename packages in such a way to make the linter happy. * [NOD-828] Finish satisfying the linter. * [NOD-828] Fix doc.go. * [NOD-828] Fix comments in block.go. * [NOD-828] Move dbaccess out of the database package. * [NOD-828] Move opening/closing the database to dbaccess. * [NOD-828] Move the Database interface to the root database package, since it's meant to be generic. * [NOD-828] Make ffldb generic to later support additional databases. * [NOD-828] Make ffldb.Open return DatabaseHandle, since ffldb is no longer exported. * [NOD-828] Fix comments. * [NOD-828] Rename AppendFlatData to AppendToStore and RetrieveFlatData to RetrieveFromStore. * [NOD-828] Make buckets nicer to use. * [NOD-828] Implement cursors that iterate over some bucket. * [NOD-828] Generalize flat-file repairing and move block database repairing into ffldb. * [NOD-828] Write a test making sure that flat file repair works. * [NOD-828] Properly close the database in TestRepairFlatFiles. * [NOD-828] Add a comment warning against putting and getting the same data within the same transaction. * [NOD-828] Fix the flatFilesBucket description. * [NOD-828] Remove superfluous whitespace. * [NOD-828] Fix the ffldb description. * [NOD-828] Rename Database to DataAccessor and rename Handle to Database. * [NOD-828] Make Get return nil if the value doesn't exist. * [NOD-828] Attempt to close leveldb even if closing ffdb failed. * [NOD-828] Fix a bug where the wrong location would be written to the current store location bucket. * [NOD-828] Fix not updating the store location in ffldb transactions. * [NOD-828] Make scanFlatFiles return an error if os.Stat fails for any reason other than file-not-found. * [NOD-828] Update the README and doc.go. * [NOD-828] Simplify Bucket.Path(). * [NOD-828] Since LevelDBCursor satisfied the database2.Cursor interface, use it directly. * [NOD-828] Combine two lines into one. * [NOD-828] Combine another two lines into one. * [NOD-828] Move a misplaced comment. * [NOD-828] Use Wrapf instead of Errorf where appropriate. * [NOD-828] Fix a comment. * [NOD-828] Fix a comment. * [NOD-828] Fix Wrapf calls. * [NOD-828] Fix comments. * [NOD-828] Remove superfluous whitespace. * [NOD-828] Add a comment explaining the use of batches and snapshots. * [NOD-828] Implement RollbackUnlessClosed(). * [NOD-828] Return both errors in StoreBlock rollback. * [NOD-828] Move rollback-on-error logic into ffldb. Remove CurrentStoreLocation and RollbackStore from DataAccessor. * [NOD-828] Make bucket a type alias instead of a struct. * [NOD-828] Fix a typo. * [NOD-828] Use copy instead of append in Bucket. * [NOD-828] Extract flatFileLocationSerializedSize to a const. * [NOD-828] Debugf -> Warnf in rollback.go. * [NOD-828] Fix a comment. * [NOD-828] Fix a comment. * [NOD-828] Remove data length from flat file data format. * [NOD-828] Rearrange TestLevelDBTransactionSanity a bit. * [NOD-828] Add stack traces to all errors that come out of library functions. * [NOD-828] Return errors from rollback(). * [NOD-828] Remove an irrelevant comment. * [NOD-828] Remove redundant whitespace. * [NOD-828] Handle nil in FetchBlock. * [NOD-828] Move the explanation about batches and snapshots to the LevelDBTransaction struct. * Revert "[NOD-828] Make bucket a type alias instead of a struct." This reverts commit 1fd39652 * [NOD-828] Fix revert errors. * Revert "[NOD-828] Remove data length from flat file data format." This reverts commit ef408e32 * [NOD-862] Move Cursor() into the DataAccessor interface. * [NOD-828] Add Delete to DataAccessor. * [NOD-865] Move fee data db operations to dbaccess * [NOD-865] Move reachability data db operations to dbaccess * [NOD-865] Move UTXO diff data db operations to dbaccess * [NOD-865] Move subnetwork data db operations to dbaccess * [NOD-865] Fix createDAGState * [NOD-865] Remove old Get signature with "exists" * [NOD-865] Move multiset db operations to dbaccess * [NOD-865] Use dbaccess transactions where possible * [NOD-865] Remove old Get signature with "exists" * [NOD-881] Recover TestGHOSTDAGErrors * [NOD-865] Create function for db keys * [NOD-865] Change Exists to Has, and use accessor.Has where possible * [NOD-865] Make ClearReachabilityData transactive * [NOD-865] Don't iterate cursors while changing db data * [NOD-865] Rename RegisterSubnetwork -> StoreSubnetwork * [NOD-865] Change bucket from utxodiffs to utxo-diffs * [NOD-865] Rename SubnetworkExists->HasSubnetwork * [NOD-865] Change a comment * [NOD-865] Fix tests * [NOD-865] Fix comment * [NOD-865] Remove the prefix "db" from some functions * [NOD-865] Remove redundant comments * [NOD-865] Make clearBucket function * [NOD-865] Make clear functions get a dbTx as an arg * [NOD-865] Remove erroneous tx commit Co-authored-by: stasatdaglabs <stas@daglabs.com> * [NOD-868] Delete the old database package (#683) * [NOD-828] Create the database2 package that will some day replace the database package. * [NOD-828] Implement a "bucket" key mechanism. * [NOD-828] Move bucket.go into the ffldb2 package. * [NOD-828] Delete the un-interfaced ffldb package from database2, since we aren't going to be using it anyway. * [NOD-828] Copy over + fixup flat file structs from the old ffldb. * [NOD-828] Implement flatFilePath. * [NOD-828] Implement flatFileStore.write(). * [NOD-828] Implement flatFileStore.read(). * [NOD-828] Implement flatFileStore.rollback(). * [NOD-828] Sync the file to disk at the end of write(). * [NOD-828] Extract crc32ByteOrder to a separate variable. * [NOD-828] Add a sanity test. * [NOD-828] Remove context-unrelated methods from the Database interface. * [NOD-828] Create an ffldb object. Simply work against a context. * [NOD-828] Open the new database on start. * [NOD-828] Create the leveldb package. * [NOD-828] Implement opening/closing leveldb. * [NOD-828] Implement get/put out of/into leveldb. * [NOD-828] Implement transactions and make them implement a generic database interface. * [NOD-828] Write sanity tests for leveldb with and without transactions. * [NOD-828] Add another case to the transaction sanity test. * [NOD-828] Implement AppendBlock/RetrieveBlock. * [NOD-828] Refactor so that concepts such as "block" and "metadata" don't leak into the database package. * [NOD-828] Add RollbackFlatData to the database interface. * [NOD-828] Remove anything from dbaccess that I'm not planning to implement as part of this ticket. * [NOD-828] Implement StoreBlock. * [NOD-828] Implement FetchBlock. * [NOD-828] Implement HasBlock. * [NOD-828] Write a sanity test for block insertion. * [NOD-828] Implement CurrentFlatDataLocation. * [NOD-828] Implement storing the current block location. * [NOD-828] Implement initializing/syncing the flat file block store and the "metadata". * [NOD-828] Add InitBlockStore to TestBlockStoreSanity. * [NOD-828] Fix rename errors. * [NOD-828] Fix lint errors in the root database package. * [NOD-828] Fix lint errors in the ffldb.go. * [NOD-828] Fix lint errors in the flatfile/db.go. * [NOD-828] Rename packages in such a way to make the linter happy. * [NOD-828] Finish satisfying the linter. * [NOD-828] Fix doc.go. * [NOD-828] Fix comments in block.go. * [NOD-828] Move dbaccess out of the database package. * [NOD-828] Move opening/closing the database to dbaccess. * [NOD-828] Move the Database interface to the root database package, since it's meant to be generic. * [NOD-828] Make ffldb generic to later support additional databases. * [NOD-828] Make ffldb.Open return DatabaseHandle, since ffldb is no longer exported. * [NOD-828] Fix comments. * [NOD-828] Rename AppendFlatData to AppendToStore and RetrieveFlatData to RetrieveFromStore. * [NOD-828] Make buckets nicer to use. * [NOD-828] Implement cursors that iterate over some bucket. * [NOD-828] Generalize flat-file repairing and move block database repairing into ffldb. * [NOD-828] Write a test making sure that flat file repair works. * [NOD-828] Properly close the database in TestRepairFlatFiles. * [NOD-828] Add a comment warning against putting and getting the same data within the same transaction. * [NOD-828] Fix the flatFilesBucket description. * [NOD-828] Remove superfluous whitespace. * [NOD-828] Fix the ffldb description. * [NOD-828] Rename Database to DataAccessor and rename Handle to Database. * [NOD-828] Make Get return nil if the value doesn't exist. * [NOD-828] Attempt to close leveldb even if closing ffdb failed. * [NOD-828] Fix a bug where the wrong location would be written to the current store location bucket. * [NOD-828] Fix not updating the store location in ffldb transactions. * [NOD-828] Make scanFlatFiles return an error if os.Stat fails for any reason other than file-not-found. * [NOD-828] Update the README and doc.go. * [NOD-828] Simplify Bucket.Path(). * [NOD-828] Since LevelDBCursor satisfied the database2.Cursor interface, use it directly. * [NOD-828] Combine two lines into one. * [NOD-828] Combine another two lines into one. * [NOD-828] Move a misplaced comment. * [NOD-828] Use Wrapf instead of Errorf where appropriate. * [NOD-828] Fix a comment. * [NOD-828] Fix a comment. * [NOD-828] Fix Wrapf calls. * [NOD-828] Fix comments. * [NOD-828] Remove superfluous whitespace. * [NOD-828] Add a comment explaining the use of batches and snapshots. * [NOD-828] Implement RollbackUnlessClosed(). * [NOD-828] Return both errors in StoreBlock rollback. * [NOD-828] Move rollback-on-error logic into ffldb. Remove CurrentStoreLocation and RollbackStore from DataAccessor. * [NOD-828] Make bucket a type alias instead of a struct. * [NOD-828] Fix a typo. * [NOD-828] Use copy instead of append in Bucket. * [NOD-828] Extract flatFileLocationSerializedSize to a const. * [NOD-828] Debugf -> Warnf in rollback.go. * [NOD-828] Fix a comment. * [NOD-828] Fix a comment. * [NOD-828] Remove data length from flat file data format. * [NOD-828] Rearrange TestLevelDBTransactionSanity a bit. * [NOD-828] Add stack traces to all errors that come out of library functions. * [NOD-828] Return errors from rollback(). * [NOD-828] Remove an irrelevant comment. * [NOD-828] Remove redundant whitespace. * [NOD-828] Handle nil in FetchBlock. * [NOD-828] Move the explanation about batches and snapshots to the LevelDBTransaction struct. * Revert "[NOD-828] Make bucket a type alias instead of a struct." This reverts commit 1fd39652 * [NOD-828] Fix revert errors. * Revert "[NOD-828] Remove data length from flat file data format." This reverts commit ef408e32 * [NOD-862] Move Cursor() into the DataAccessor interface. * [NOD-828] Add Delete to DataAccessor. * [NOD-865] Move fee data db operations to dbaccess * [NOD-865] Move reachability data db operations to dbaccess * [NOD-865] Move UTXO diff data db operations to dbaccess * [NOD-865] Move subnetwork data db operations to dbaccess * [NOD-865] Fix createDAGState * [NOD-865] Remove old Get signature with "exists" * [NOD-865] Move multiset db operations to dbaccess * [NOD-865] Use dbaccess transactions where possible * [NOD-865] Remove old Get signature with "exists" * [NOD-881] Recover TestGHOSTDAGErrors * [NOD-865] Create function for db keys * [NOD-865] Change Exists to Has, and use accessor.Has where possible * [NOD-865] Make ClearReachabilityData transactive * [NOD-865] Don't iterate cursors while changing db data * [NOD-865] Rename RegisterSubnetwork -> StoreSubnetwork * [NOD-865] Change bucket from utxodiffs to utxo-diffs * [NOD-865] Rename SubnetworkExists->HasSubnetwork * [NOD-865] Change a comment * [NOD-868] Remove all tests from old database. * [NOD-868] Remove all unused methods from the old database's interfaces. * [NOD-865] Fix tests * [NOD-868] Remove references to DB. * [NOD-865] Fix comment * [NOD-868] Remove the old ffldb besides the interface and errors.go. * [NOD-868] Remove errors.go. * [NOD-868] Remove the old database package. * [NOD-868] Add openDB to DAGSetup to emulate the old dbpath in dag.config. * [NOD-868] Rename database2 to database. * [NOD-868] Use NewTx instead of NoTx where required. * [NOD-868] Fix merge errors. * [NOD-868] Rename dbXXX functions to just xxx. * [NOD-868] Rename putDAGState to saveDAGState. * [NOD-868] Replace comments in initDAGState with logs. * [NOD-868] Explain the openDB parameter in DAGSetup. * [NOD-868] Fixup doc.go and README.md. * [NOD-868] Remove pointless transactions. Co-authored-by: Ori Newman <orinewman1@gmail.com> * [NOD-805] Fix merge errors. * [NOD-805] Fix a comment. * [NOD-805] Don't return virtualTxsAcceptanceData from applyDAGChanges. * [NOD-805] Add missing error handling in TestAcceptanceDataIndexRecover. * [NOD-805] Rename blockDAG to dag in indexers/manager.go. * [NOD-805] Defer cursor.Close() everywhere. * [NOD-805] Rename scanFlatFiles to findCurrentLocation. * [NOD-805] Extract crc32ChecksumLength and dataLengthLength to constants. * [NOD-805] Handle open files properly in rollback.go. * [NOD-805] Remove unnecessary func wrapper. * [NOD-805] Remove unnecessary trimming in initialize. * [NOD-805] Made StoreBlock accept only TxContext. * [NOD-805] Changed the log level of an error message to Error. * [NOD-805] Add a note about holding mutexes over deleteFile. * [NOD-805] Remove a false comment. * [NOD-805] Fix a comment. * [NOD-805] Rename blk to block. * [NOD-805] Extract utxoKey to a separate function. * [NOD-805] Move dbaccess.xxxKey functions to the tops of their respective files. * [NOD-805] Fix grammar in dbaccess/db.go. * [NOD-805] Wrap a failed database corruption recovery error. * [NOD-805] Split lines with WithStack in them. * [NOD-805] Fix the comment over initialize. * [NOD-805] Rename ffdb to flatFileDB and ldb to levelDB. * [NOD-805] Fix a comment. * [NOD-805] Fix a comment. * [NOD-805] Use s.writeCursor instead of cursor. * [NOD-805] Embed file in lockableFile. * [NOD-805] the the -> the * [NOD-805] openDB -> db * [NOD-805] Use TxContext in all flushToDB functions. * [NOD-805] Rename context -> dbContext. * [NOD-805] Reword the comment at the beginning on initDAGState. * [NOD-805] Explain cursor key trimming. * [NOD-805] Remove Error from Cursor. * [NOD-805] Return ErrNotFound from done Cursor Key and Value. * [NOD-805] Add missing error handling. * [NOD-805] Fix a comment. * [NOD-805] Fix a variable name. * [NOD-805] Remove pointless underscore. * [NOD-805] Fix a comment. * [NOD-805] Fix a variable name. Co-authored-by: Mike Zak <feanorr@gmail.com> Co-authored-by: Ori Newman <orinewman1@gmail.com>
1327 lines
43 KiB
Go
1327 lines
43 KiB
Go
// Copyright (c) 2013-2017 The btcsuite developers
|
|
// Use of this source code is governed by an ISC
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package blockdag
|
|
|
|
import (
|
|
"github.com/pkg/errors"
|
|
"math"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/kaspanet/kaspad/dagconfig"
|
|
"github.com/kaspanet/kaspad/util"
|
|
"github.com/kaspanet/kaspad/util/daghash"
|
|
"github.com/kaspanet/kaspad/util/subnetworkid"
|
|
"github.com/kaspanet/kaspad/wire"
|
|
)
|
|
|
|
// TestSequenceLocksActive tests the SequenceLockActive function to ensure it
|
|
// works as expected in all possible combinations/scenarios.
|
|
func TestSequenceLocksActive(t *testing.T) {
|
|
seqLock := func(h int64, s int64) *SequenceLock {
|
|
return &SequenceLock{
|
|
Seconds: s,
|
|
BlockBlueScore: h,
|
|
}
|
|
}
|
|
|
|
tests := []struct {
|
|
seqLock *SequenceLock
|
|
blockBlueScore uint64
|
|
mtp time.Time
|
|
|
|
want bool
|
|
}{
|
|
// Block based sequence lock with equal block blue score.
|
|
{seqLock: seqLock(1000, -1), blockBlueScore: 1001, mtp: time.Unix(9, 0), want: true},
|
|
|
|
// Time based sequence lock with mtp past the absolute time.
|
|
{seqLock: seqLock(-1, 30), blockBlueScore: 2, mtp: time.Unix(31, 0), want: true},
|
|
|
|
// Block based sequence lock with current blue score below seq lock block blue score.
|
|
{seqLock: seqLock(1000, -1), blockBlueScore: 90, mtp: time.Unix(9, 0), want: false},
|
|
|
|
// Time based sequence lock with current time before lock time.
|
|
{seqLock: seqLock(-1, 30), blockBlueScore: 2, mtp: time.Unix(29, 0), want: false},
|
|
|
|
// Block based sequence lock at the same blue score, so shouldn't yet be active.
|
|
{seqLock: seqLock(1000, -1), blockBlueScore: 1000, mtp: time.Unix(9, 0), want: false},
|
|
|
|
// Time based sequence lock with current time equal to lock time, so shouldn't yet be active.
|
|
{seqLock: seqLock(-1, 30), blockBlueScore: 2, mtp: time.Unix(30, 0), want: false},
|
|
}
|
|
|
|
t.Logf("Running %d sequence locks tests", len(tests))
|
|
for i, test := range tests {
|
|
got := SequenceLockActive(test.seqLock,
|
|
test.blockBlueScore, test.mtp)
|
|
if got != test.want {
|
|
t.Fatalf("SequenceLockActive #%d got %v want %v", i,
|
|
got, test.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestCheckConnectBlockTemplate tests the CheckConnectBlockTemplate function to
|
|
// ensure it fails.
|
|
func TestCheckConnectBlockTemplate(t *testing.T) {
|
|
// Create a new database and DAG instance to run tests against.
|
|
dag, teardownFunc, err := DAGSetup("checkconnectblocktemplate", true, Config{
|
|
DAGParams: &dagconfig.SimnetParams,
|
|
})
|
|
if err != nil {
|
|
t.Errorf("Failed to setup dag instance: %v", err)
|
|
return
|
|
}
|
|
defer teardownFunc()
|
|
|
|
// Since we're not dealing with the real block DAG, set the coinbase
|
|
// maturity to 0.
|
|
dag.TestSetCoinbaseMaturity(0)
|
|
|
|
// Load up blocks such that there is a side chain.
|
|
// (genesis block) -> 1 -> 2 -> 3 -> 4
|
|
// \-> 3a
|
|
testFiles := []string{
|
|
"blk_0_to_4.dat",
|
|
"blk_3B.dat",
|
|
}
|
|
|
|
var blocks []*util.Block
|
|
for _, file := range testFiles {
|
|
blockTmp, err := LoadBlocks(filepath.Join("testdata/", file))
|
|
if err != nil {
|
|
t.Fatalf("Error loading file: %v\n", err)
|
|
}
|
|
blocks = append(blocks, blockTmp...)
|
|
}
|
|
|
|
for i := 1; i <= 3; i++ {
|
|
_, isDelayed, err := dag.ProcessBlock(blocks[i], BFNone)
|
|
if err != nil {
|
|
t.Fatalf("CheckConnectBlockTemplate: Received unexpected error "+
|
|
"processing block %d: %v", i, err)
|
|
}
|
|
if isDelayed {
|
|
t.Fatalf("CheckConnectBlockTemplate: block %d is too far in the future", i)
|
|
}
|
|
}
|
|
|
|
// Block 3 should fail to connect since it's already inserted.
|
|
err = dag.CheckConnectBlockTemplateNoLock(blocks[3])
|
|
if err == nil {
|
|
t.Fatal("CheckConnectBlockTemplate: Did not received expected error " +
|
|
"on block 3")
|
|
}
|
|
|
|
// Block 4 should connect successfully to tip of chain.
|
|
err = dag.CheckConnectBlockTemplateNoLock(blocks[4])
|
|
if err != nil {
|
|
t.Fatalf("CheckConnectBlockTemplate: Received unexpected error on "+
|
|
"block 4: %v", err)
|
|
}
|
|
|
|
blockNode3 := dag.index.LookupNode(blocks[3].Hash())
|
|
blockNode4 := dag.index.LookupNode(blocks[4].Hash())
|
|
if blockNode3.children.contains(blockNode4) {
|
|
t.Errorf("Block 4 wasn't successfully detached as a child from block3")
|
|
}
|
|
|
|
// Block 3a should connect even though it does not build on dag tips.
|
|
err = dag.CheckConnectBlockTemplateNoLock(blocks[5])
|
|
if err != nil {
|
|
t.Fatal("CheckConnectBlockTemplate: Recieved unexpected error on " +
|
|
"block 3a that connects below the tips")
|
|
}
|
|
|
|
// Block 4 should connect even if proof of work is invalid.
|
|
invalidPowMsgBlock := *blocks[4].MsgBlock()
|
|
invalidPowMsgBlock.Header.Nonce++
|
|
invalidPowBlock := util.NewBlock(&invalidPowMsgBlock)
|
|
err = dag.CheckConnectBlockTemplateNoLock(invalidPowBlock)
|
|
if err != nil {
|
|
t.Fatalf("CheckConnectBlockTemplate: Received unexpected error on "+
|
|
"block 4 with bad nonce: %v", err)
|
|
}
|
|
|
|
// Invalid block building on chain tip should fail to connect.
|
|
invalidBlock := *blocks[4].MsgBlock()
|
|
invalidBlock.Header.Bits--
|
|
err = dag.CheckConnectBlockTemplateNoLock(util.NewBlock(&invalidBlock))
|
|
if err == nil {
|
|
t.Fatal("CheckConnectBlockTemplate: Did not received expected error " +
|
|
"on block 4 with invalid difficulty bits")
|
|
}
|
|
}
|
|
|
|
// TestCheckBlockSanity tests the CheckBlockSanity function to ensure it works
|
|
// as expected.
|
|
func TestCheckBlockSanity(t *testing.T) {
|
|
// Create a new database and dag instance to run tests against.
|
|
dag, teardownFunc, err := DAGSetup("TestCheckBlockSanity", true, Config{
|
|
DAGParams: &dagconfig.SimnetParams,
|
|
})
|
|
if err != nil {
|
|
t.Errorf("Failed to setup dag instance: %v", err)
|
|
return
|
|
}
|
|
defer teardownFunc()
|
|
dag.timeSource = newFakeTimeSource(time.Now())
|
|
|
|
block := util.NewBlock(&Block100000)
|
|
if len(block.Transactions()) < 3 {
|
|
t.Fatalf("Too few transactions in block, expect at least 3, got %v", len(block.Transactions()))
|
|
}
|
|
delay, err := dag.checkBlockSanity(block, BFNone)
|
|
if err != nil {
|
|
t.Errorf("CheckBlockSanity: %v", err)
|
|
}
|
|
if delay != 0 {
|
|
t.Errorf("CheckBlockSanity: unexpected return %s delay", delay)
|
|
}
|
|
// Test with block with wrong transactions sorting order
|
|
blockWithWrongTxOrder := util.NewBlock(&BlockWithWrongTxOrder)
|
|
delay, err = dag.checkBlockSanity(blockWithWrongTxOrder, BFNone)
|
|
if err == nil {
|
|
t.Errorf("CheckBlockSanity: transactions disorder is not detected")
|
|
}
|
|
var ruleErr RuleError
|
|
if !errors.As(err, &ruleErr) {
|
|
t.Errorf("CheckBlockSanity: wrong error returned, expect RuleError, got %T", err)
|
|
} else if ruleErr.ErrorCode != ErrTransactionsNotSorted {
|
|
t.Errorf("CheckBlockSanity: wrong error returned, expect ErrTransactionsNotSorted, got"+
|
|
" %v, err %s", ruleErr.ErrorCode, err)
|
|
}
|
|
if delay != 0 {
|
|
t.Errorf("CheckBlockSanity: unexpected return %s delay", delay)
|
|
}
|
|
|
|
// Ensure a block that has a timestamp with a precision higher than one
|
|
// second fails.
|
|
timestamp := block.MsgBlock().Header.Timestamp
|
|
block.MsgBlock().Header.Timestamp = timestamp.Add(time.Nanosecond)
|
|
delay, err = dag.checkBlockSanity(block, BFNone)
|
|
if err == nil {
|
|
t.Errorf("CheckBlockSanity: error is nil when it shouldn't be")
|
|
}
|
|
if delay != 0 {
|
|
t.Errorf("CheckBlockSanity: unexpected return %s delay", delay)
|
|
}
|
|
|
|
var invalidParentsOrderBlock = wire.MsgBlock{
|
|
Header: wire.BlockHeader{
|
|
Version: 0x10000000,
|
|
ParentHashes: []*daghash.Hash{
|
|
{
|
|
0x4b, 0xb0, 0x75, 0x35, 0xdf, 0xd5, 0x8e, 0x0b,
|
|
0x3c, 0xd6, 0x4f, 0xd7, 0x15, 0x52, 0x80, 0x87,
|
|
0x2a, 0x04, 0x71, 0xbc, 0xf8, 0x30, 0x95, 0x52,
|
|
0x6a, 0xce, 0x0e, 0x38, 0xc6, 0x00, 0x00, 0x00,
|
|
},
|
|
{
|
|
0x16, 0x5e, 0x38, 0xe8, 0xb3, 0x91, 0x45, 0x95,
|
|
0xd9, 0xc6, 0x41, 0xf3, 0xb8, 0xee, 0xc2, 0xf3,
|
|
0x46, 0x11, 0x89, 0x6b, 0x82, 0x1a, 0x68, 0x3b,
|
|
0x7a, 0x4e, 0xde, 0xfe, 0x2c, 0x00, 0x00, 0x00,
|
|
},
|
|
},
|
|
HashMerkleRoot: &daghash.Hash{
|
|
0x2f, 0x4c, 0xc3, 0x0b, 0x0a, 0x84, 0xbb, 0x95,
|
|
0x56, 0x9d, 0x77, 0xa2, 0xee, 0x3e, 0xb1, 0xac,
|
|
0x48, 0x3e, 0x8b, 0xe1, 0xcf, 0xdc, 0x20, 0xba,
|
|
0xae, 0xec, 0x0a, 0x2f, 0xe4, 0x85, 0x31, 0x30,
|
|
},
|
|
AcceptedIDMerkleRoot: &daghash.Hash{
|
|
0x80, 0xf7, 0x00, 0xe3, 0x16, 0x3d, 0x04, 0x95,
|
|
0x5b, 0x7e, 0xaf, 0x84, 0x7e, 0x1b, 0x6b, 0x06,
|
|
0x4e, 0x06, 0xba, 0x64, 0xd7, 0x61, 0xda, 0x25,
|
|
0x1a, 0x0e, 0x21, 0xd4, 0x64, 0x49, 0x02, 0xa2,
|
|
},
|
|
UTXOCommitment: &daghash.Hash{
|
|
0x80, 0xf7, 0x00, 0xe3, 0x16, 0x3d, 0x04, 0x95,
|
|
0x5b, 0x7e, 0xaf, 0x84, 0x7e, 0x1b, 0x6b, 0x06,
|
|
0x4e, 0x06, 0xba, 0x64, 0xd7, 0x61, 0xda, 0x25,
|
|
0x1a, 0x0e, 0x21, 0xd4, 0x64, 0x49, 0x02, 0xa2,
|
|
},
|
|
Timestamp: time.Unix(0x5cd18053, 0),
|
|
Bits: 0x207fffff,
|
|
Nonce: 0x1,
|
|
},
|
|
Transactions: []*wire.MsgTx{
|
|
{
|
|
Version: 1,
|
|
TxIn: []*wire.TxIn{
|
|
{
|
|
PreviousOutpoint: wire.Outpoint{
|
|
TxID: daghash.TxID{},
|
|
Index: 0xffffffff,
|
|
},
|
|
SignatureScript: []byte{
|
|
0x02, 0x10, 0x27, 0x08, 0xac, 0x29, 0x2f, 0x2f,
|
|
0xcf, 0x70, 0xb0, 0x7e, 0x0b, 0x2f, 0x50, 0x32,
|
|
0x53, 0x48, 0x2f, 0x62, 0x74, 0x63, 0x64, 0x2f,
|
|
},
|
|
Sequence: math.MaxUint64,
|
|
},
|
|
},
|
|
TxOut: []*wire.TxOut{
|
|
{
|
|
Value: 0x12a05f200, // 5000000000
|
|
ScriptPubKey: []byte{
|
|
0x51,
|
|
},
|
|
},
|
|
},
|
|
LockTime: 0,
|
|
SubnetworkID: *subnetworkid.SubnetworkIDNative,
|
|
},
|
|
{
|
|
Version: 1,
|
|
TxIn: []*wire.TxIn{
|
|
{
|
|
PreviousOutpoint: wire.Outpoint{
|
|
TxID: daghash.TxID([32]byte{
|
|
0x03, 0x2e, 0x38, 0xe9, 0xc0, 0xa8, 0x4c, 0x60,
|
|
0x46, 0xd6, 0x87, 0xd1, 0x05, 0x56, 0xdc, 0xac,
|
|
0xc4, 0x1d, 0x27, 0x5e, 0xc5, 0x5f, 0xc0, 0x07,
|
|
0x79, 0xac, 0x88, 0xfd, 0xf3, 0x57, 0xa1, 0x87,
|
|
}), // 87a157f3fd88ac7907c05fc55e271dc4acdc5605d187d646604ca8c0e9382e03
|
|
Index: 0,
|
|
},
|
|
SignatureScript: []byte{
|
|
0x49, // OP_DATA_73
|
|
0x30, 0x46, 0x02, 0x21, 0x00, 0xc3, 0x52, 0xd3,
|
|
0xdd, 0x99, 0x3a, 0x98, 0x1b, 0xeb, 0xa4, 0xa6,
|
|
0x3a, 0xd1, 0x5c, 0x20, 0x92, 0x75, 0xca, 0x94,
|
|
0x70, 0xab, 0xfc, 0xd5, 0x7d, 0xa9, 0x3b, 0x58,
|
|
0xe4, 0xeb, 0x5d, 0xce, 0x82, 0x02, 0x21, 0x00,
|
|
0x84, 0x07, 0x92, 0xbc, 0x1f, 0x45, 0x60, 0x62,
|
|
0x81, 0x9f, 0x15, 0xd3, 0x3e, 0xe7, 0x05, 0x5c,
|
|
0xf7, 0xb5, 0xee, 0x1a, 0xf1, 0xeb, 0xcc, 0x60,
|
|
0x28, 0xd9, 0xcd, 0xb1, 0xc3, 0xaf, 0x77, 0x48,
|
|
0x01, // 73-byte signature
|
|
0x41, // OP_DATA_65
|
|
0x04, 0xf4, 0x6d, 0xb5, 0xe9, 0xd6, 0x1a, 0x9d,
|
|
0xc2, 0x7b, 0x8d, 0x64, 0xad, 0x23, 0xe7, 0x38,
|
|
0x3a, 0x4e, 0x6c, 0xa1, 0x64, 0x59, 0x3c, 0x25,
|
|
0x27, 0xc0, 0x38, 0xc0, 0x85, 0x7e, 0xb6, 0x7e,
|
|
0xe8, 0xe8, 0x25, 0xdc, 0xa6, 0x50, 0x46, 0xb8,
|
|
0x2c, 0x93, 0x31, 0x58, 0x6c, 0x82, 0xe0, 0xfd,
|
|
0x1f, 0x63, 0x3f, 0x25, 0xf8, 0x7c, 0x16, 0x1b,
|
|
0xc6, 0xf8, 0xa6, 0x30, 0x12, 0x1d, 0xf2, 0xb3,
|
|
0xd3, // 65-byte pubkey
|
|
},
|
|
Sequence: math.MaxUint64,
|
|
},
|
|
},
|
|
TxOut: []*wire.TxOut{
|
|
{
|
|
Value: 0x2123e300, // 556000000
|
|
ScriptPubKey: []byte{
|
|
0x76, // OP_DUP
|
|
0xa9, // OP_HASH160
|
|
0x14, // OP_DATA_20
|
|
0xc3, 0x98, 0xef, 0xa9, 0xc3, 0x92, 0xba, 0x60,
|
|
0x13, 0xc5, 0xe0, 0x4e, 0xe7, 0x29, 0x75, 0x5e,
|
|
0xf7, 0xf5, 0x8b, 0x32,
|
|
0x88, // OP_EQUALVERIFY
|
|
0xac, // OP_CHECKSIG
|
|
},
|
|
},
|
|
{
|
|
Value: 0x108e20f00, // 4444000000
|
|
ScriptPubKey: []byte{
|
|
0x76, // OP_DUP
|
|
0xa9, // OP_HASH160
|
|
0x14, // OP_DATA_20
|
|
0x94, 0x8c, 0x76, 0x5a, 0x69, 0x14, 0xd4, 0x3f,
|
|
0x2a, 0x7a, 0xc1, 0x77, 0xda, 0x2c, 0x2f, 0x6b,
|
|
0x52, 0xde, 0x3d, 0x7c,
|
|
0x88, // OP_EQUALVERIFY
|
|
0xac, // OP_CHECKSIG
|
|
},
|
|
},
|
|
},
|
|
LockTime: 0,
|
|
SubnetworkID: *subnetworkid.SubnetworkIDNative,
|
|
},
|
|
{
|
|
Version: 1,
|
|
TxIn: []*wire.TxIn{
|
|
{
|
|
PreviousOutpoint: wire.Outpoint{
|
|
TxID: daghash.TxID([32]byte{
|
|
0xc3, 0x3e, 0xbf, 0xf2, 0xa7, 0x09, 0xf1, 0x3d,
|
|
0x9f, 0x9a, 0x75, 0x69, 0xab, 0x16, 0xa3, 0x27,
|
|
0x86, 0xaf, 0x7d, 0x7e, 0x2d, 0xe0, 0x92, 0x65,
|
|
0xe4, 0x1c, 0x61, 0xd0, 0x78, 0x29, 0x4e, 0xcf,
|
|
}), // cf4e2978d0611ce46592e02d7e7daf8627a316ab69759a9f3df109a7f2bf3ec3
|
|
Index: 1,
|
|
},
|
|
SignatureScript: []byte{
|
|
0x47, // OP_DATA_71
|
|
0x30, 0x44, 0x02, 0x20, 0x03, 0x2d, 0x30, 0xdf,
|
|
0x5e, 0xe6, 0xf5, 0x7f, 0xa4, 0x6c, 0xdd, 0xb5,
|
|
0xeb, 0x8d, 0x0d, 0x9f, 0xe8, 0xde, 0x6b, 0x34,
|
|
0x2d, 0x27, 0x94, 0x2a, 0xe9, 0x0a, 0x32, 0x31,
|
|
0xe0, 0xba, 0x33, 0x3e, 0x02, 0x20, 0x3d, 0xee,
|
|
0xe8, 0x06, 0x0f, 0xdc, 0x70, 0x23, 0x0a, 0x7f,
|
|
0x5b, 0x4a, 0xd7, 0xd7, 0xbc, 0x3e, 0x62, 0x8c,
|
|
0xbe, 0x21, 0x9a, 0x88, 0x6b, 0x84, 0x26, 0x9e,
|
|
0xae, 0xb8, 0x1e, 0x26, 0xb4, 0xfe, 0x01,
|
|
0x41, // OP_DATA_65
|
|
0x04, 0xae, 0x31, 0xc3, 0x1b, 0xf9, 0x12, 0x78,
|
|
0xd9, 0x9b, 0x83, 0x77, 0xa3, 0x5b, 0xbc, 0xe5,
|
|
0xb2, 0x7d, 0x9f, 0xff, 0x15, 0x45, 0x68, 0x39,
|
|
0xe9, 0x19, 0x45, 0x3f, 0xc7, 0xb3, 0xf7, 0x21,
|
|
0xf0, 0xba, 0x40, 0x3f, 0xf9, 0x6c, 0x9d, 0xee,
|
|
0xb6, 0x80, 0xe5, 0xfd, 0x34, 0x1c, 0x0f, 0xc3,
|
|
0xa7, 0xb9, 0x0d, 0xa4, 0x63, 0x1e, 0xe3, 0x95,
|
|
0x60, 0x63, 0x9d, 0xb4, 0x62, 0xe9, 0xcb, 0x85,
|
|
0x0f, // 65-byte pubkey
|
|
},
|
|
Sequence: math.MaxUint64,
|
|
},
|
|
},
|
|
TxOut: []*wire.TxOut{
|
|
{
|
|
Value: 0xf4240, // 1000000
|
|
ScriptPubKey: []byte{
|
|
0x76, // OP_DUP
|
|
0xa9, // OP_HASH160
|
|
0x14, // OP_DATA_20
|
|
0xb0, 0xdc, 0xbf, 0x97, 0xea, 0xbf, 0x44, 0x04,
|
|
0xe3, 0x1d, 0x95, 0x24, 0x77, 0xce, 0x82, 0x2d,
|
|
0xad, 0xbe, 0x7e, 0x10,
|
|
0x88, // OP_EQUALVERIFY
|
|
0xac, // OP_CHECKSIG
|
|
},
|
|
},
|
|
{
|
|
Value: 0x11d260c0, // 299000000
|
|
ScriptPubKey: []byte{
|
|
0x76, // OP_DUP
|
|
0xa9, // OP_HASH160
|
|
0x14, // OP_DATA_20
|
|
0x6b, 0x12, 0x81, 0xee, 0xc2, 0x5a, 0xb4, 0xe1,
|
|
0xe0, 0x79, 0x3f, 0xf4, 0xe0, 0x8a, 0xb1, 0xab,
|
|
0xb3, 0x40, 0x9c, 0xd9,
|
|
0x88, // OP_EQUALVERIFY
|
|
0xac, // OP_CHECKSIG
|
|
},
|
|
},
|
|
},
|
|
LockTime: 0,
|
|
SubnetworkID: *subnetworkid.SubnetworkIDNative,
|
|
},
|
|
{
|
|
Version: 1,
|
|
TxIn: []*wire.TxIn{
|
|
{
|
|
PreviousOutpoint: wire.Outpoint{
|
|
TxID: daghash.TxID([32]byte{
|
|
0x0b, 0x60, 0x72, 0xb3, 0x86, 0xd4, 0xa7, 0x73,
|
|
0x23, 0x52, 0x37, 0xf6, 0x4c, 0x11, 0x26, 0xac,
|
|
0x3b, 0x24, 0x0c, 0x84, 0xb9, 0x17, 0xa3, 0x90,
|
|
0x9b, 0xa1, 0xc4, 0x3d, 0xed, 0x5f, 0x51, 0xf4,
|
|
}), // f4515fed3dc4a19b90a317b9840c243bac26114cf637522373a7d486b372600b
|
|
Index: 0,
|
|
},
|
|
SignatureScript: []byte{
|
|
0x49, // OP_DATA_73
|
|
0x30, 0x46, 0x02, 0x21, 0x00, 0xbb, 0x1a, 0xd2,
|
|
0x6d, 0xf9, 0x30, 0xa5, 0x1c, 0xce, 0x11, 0x0c,
|
|
0xf4, 0x4f, 0x7a, 0x48, 0xc3, 0xc5, 0x61, 0xfd,
|
|
0x97, 0x75, 0x00, 0xb1, 0xae, 0x5d, 0x6b, 0x6f,
|
|
0xd1, 0x3d, 0x0b, 0x3f, 0x4a, 0x02, 0x21, 0x00,
|
|
0xc5, 0xb4, 0x29, 0x51, 0xac, 0xed, 0xff, 0x14,
|
|
0xab, 0xba, 0x27, 0x36, 0xfd, 0x57, 0x4b, 0xdb,
|
|
0x46, 0x5f, 0x3e, 0x6f, 0x8d, 0xa1, 0x2e, 0x2c,
|
|
0x53, 0x03, 0x95, 0x4a, 0xca, 0x7f, 0x78, 0xf3,
|
|
0x01, // 73-byte signature
|
|
0x41, // OP_DATA_65
|
|
0x04, 0xa7, 0x13, 0x5b, 0xfe, 0x82, 0x4c, 0x97,
|
|
0xec, 0xc0, 0x1e, 0xc7, 0xd7, 0xe3, 0x36, 0x18,
|
|
0x5c, 0x81, 0xe2, 0xaa, 0x2c, 0x41, 0xab, 0x17,
|
|
0x54, 0x07, 0xc0, 0x94, 0x84, 0xce, 0x96, 0x94,
|
|
0xb4, 0x49, 0x53, 0xfc, 0xb7, 0x51, 0x20, 0x65,
|
|
0x64, 0xa9, 0xc2, 0x4d, 0xd0, 0x94, 0xd4, 0x2f,
|
|
0xdb, 0xfd, 0xd5, 0xaa, 0xd3, 0xe0, 0x63, 0xce,
|
|
0x6a, 0xf4, 0xcf, 0xaa, 0xea, 0x4e, 0xa1, 0x4f,
|
|
0xbb, // 65-byte pubkey
|
|
},
|
|
Sequence: math.MaxUint64,
|
|
},
|
|
},
|
|
TxOut: []*wire.TxOut{
|
|
{
|
|
Value: 0xf4240, // 1000000
|
|
ScriptPubKey: []byte{
|
|
0x76, // OP_DUP
|
|
0xa9, // OP_HASH160
|
|
0x14, // OP_DATA_20
|
|
0x39, 0xaa, 0x3d, 0x56, 0x9e, 0x06, 0xa1, 0xd7,
|
|
0x92, 0x6d, 0xc4, 0xbe, 0x11, 0x93, 0xc9, 0x9b,
|
|
0xf2, 0xeb, 0x9e, 0xe0,
|
|
0x88, // OP_EQUALVERIFY
|
|
0xac, // OP_CHECKSIG
|
|
},
|
|
},
|
|
},
|
|
LockTime: 0,
|
|
SubnetworkID: *subnetworkid.SubnetworkIDNative,
|
|
},
|
|
},
|
|
}
|
|
|
|
utilInvalidBlock := util.NewBlock(&invalidParentsOrderBlock)
|
|
delay, err = dag.checkBlockSanity(utilInvalidBlock, BFNone)
|
|
if err == nil {
|
|
t.Errorf("CheckBlockSanity: error is nil when it shouldn't be")
|
|
}
|
|
var rError RuleError
|
|
if !errors.As(err, &rError) {
|
|
t.Fatalf("CheckBlockSanity: expected a RuleError, but got %s", err)
|
|
} else if rError.ErrorCode != ErrWrongParentsOrder {
|
|
t.Errorf("CheckBlockSanity: Expected error was ErrWrongParentsOrder but got %v", err)
|
|
}
|
|
if delay != 0 {
|
|
t.Errorf("CheckBlockSanity: unexpected return %s delay", delay)
|
|
}
|
|
|
|
blockInTheFuture := Block100000
|
|
expectedDelay := 10 * time.Second
|
|
deviationTolerance := time.Duration(dag.TimestampDeviationTolerance*uint64(dag.targetTimePerBlock)) * time.Second
|
|
blockInTheFuture.Header.Timestamp = dag.Now().Add(deviationTolerance + expectedDelay)
|
|
delay, err = dag.checkBlockSanity(util.NewBlock(&blockInTheFuture), BFNoPoWCheck)
|
|
if err != nil {
|
|
t.Errorf("CheckBlockSanity: %v", err)
|
|
}
|
|
if delay != expectedDelay {
|
|
t.Errorf("CheckBlockSanity: expected %s delay but got %s", expectedDelay, delay)
|
|
}
|
|
}
|
|
|
|
func TestPastMedianTime(t *testing.T) {
|
|
dag := newTestDAG(&dagconfig.MainnetParams)
|
|
tip := dag.genesis
|
|
blockVersion := int32(0x10000000)
|
|
|
|
blockTime := tip.Header().Timestamp
|
|
|
|
for i := 0; i < 100; i++ {
|
|
blockTime = blockTime.Add(time.Second)
|
|
tip = newTestNode(dag, blockSetFromSlice(tip),
|
|
blockVersion,
|
|
0,
|
|
blockTime)
|
|
}
|
|
|
|
// Checks that a block is valid if it has timestamp equals to past median time
|
|
node := newTestNode(dag, blockSetFromSlice(tip),
|
|
blockVersion,
|
|
dag.powMaxBits,
|
|
tip.PastMedianTime(dag))
|
|
|
|
header := node.Header()
|
|
err := dag.checkBlockHeaderContext(header, node.parents.bluest(), false)
|
|
if err != nil {
|
|
t.Errorf("TestPastMedianTime: unexpected error from checkBlockHeaderContext: %v"+
|
|
"(a block with timestamp equals to past median time should be valid)", err)
|
|
}
|
|
|
|
// Checks that a block is valid if its timestamp is after past median time
|
|
node = newTestNode(dag, blockSetFromSlice(tip),
|
|
blockVersion,
|
|
dag.powMaxBits,
|
|
tip.PastMedianTime(dag).Add(time.Second))
|
|
|
|
header = node.Header()
|
|
err = dag.checkBlockHeaderContext(header, node.parents.bluest(), false)
|
|
if err != nil {
|
|
t.Errorf("TestPastMedianTime: unexpected error from checkBlockHeaderContext: %v"+
|
|
"(a block with timestamp bigger than past median time should be valid)", err)
|
|
}
|
|
|
|
// Checks that a block is invalid if its timestamp is before past median time
|
|
node = newTestNode(dag, blockSetFromSlice(tip),
|
|
blockVersion,
|
|
0,
|
|
tip.PastMedianTime(dag).Add(-time.Second))
|
|
|
|
header = node.Header()
|
|
err = dag.checkBlockHeaderContext(header, node.parents.bluest(), false)
|
|
if err == nil {
|
|
t.Errorf("TestPastMedianTime: unexpected success: block should be invalid if its timestamp is before past median time")
|
|
}
|
|
}
|
|
|
|
func TestValidateParents(t *testing.T) {
|
|
// Create a new database and dag instance to run tests against.
|
|
dag, teardownFunc, err := DAGSetup("TestCheckBlockSanity", true, Config{
|
|
DAGParams: &dagconfig.SimnetParams,
|
|
})
|
|
if err != nil {
|
|
t.Errorf("Failed to setup dag instance: %v", err)
|
|
return
|
|
}
|
|
defer teardownFunc()
|
|
|
|
a := prepareAndProcessBlock(t, dag, dag.dagParams.GenesisBlock)
|
|
b := prepareAndProcessBlock(t, dag, a)
|
|
c := prepareAndProcessBlock(t, dag, dag.dagParams.GenesisBlock)
|
|
|
|
aNode := nodeByMsgBlock(t, dag, a)
|
|
bNode := nodeByMsgBlock(t, dag, b)
|
|
cNode := nodeByMsgBlock(t, dag, c)
|
|
|
|
fakeBlockHeader := &wire.BlockHeader{
|
|
HashMerkleRoot: &daghash.ZeroHash,
|
|
AcceptedIDMerkleRoot: &daghash.ZeroHash,
|
|
UTXOCommitment: &daghash.ZeroHash,
|
|
}
|
|
|
|
// Check direct parents relation
|
|
err = dag.validateParents(fakeBlockHeader, blockSetFromSlice(aNode, bNode))
|
|
if err == nil {
|
|
t.Errorf("validateParents: `a` is a parent of `b`, so an error is expected")
|
|
}
|
|
|
|
// Check indirect parents relation
|
|
err = dag.validateParents(fakeBlockHeader, blockSetFromSlice(dag.genesis, bNode))
|
|
if err == nil {
|
|
t.Errorf("validateParents: `genesis` and `b` are indirectly related, so an error is expected")
|
|
}
|
|
|
|
// Check parents with no relation
|
|
err = dag.validateParents(fakeBlockHeader, blockSetFromSlice(bNode, cNode))
|
|
if err != nil {
|
|
t.Errorf("validateParents: unexpected error: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestCheckTransactionSanity(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
numInputs uint32
|
|
numOutputs uint32
|
|
outputValue uint64
|
|
nodeSubnetworkID subnetworkid.SubnetworkID
|
|
txSubnetworkData *txSubnetworkData
|
|
extraModificationsFunc func(*wire.MsgTx)
|
|
expectedErr error
|
|
}{
|
|
{"good one", 1, 1, 1, *subnetworkid.SubnetworkIDNative, nil, nil, nil},
|
|
{"no inputs", 0, 1, 1, *subnetworkid.SubnetworkIDNative, nil, nil, ruleError(ErrNoTxInputs, "")},
|
|
{"no outputs", 1, 0, 1, *subnetworkid.SubnetworkIDNative, nil, nil, nil},
|
|
{"too massive", 1, 1000000, 1, *subnetworkid.SubnetworkIDNative, nil, nil, ruleError(ErrTxMassTooHigh, "")},
|
|
{"too much sompi in one output", 1, 1, util.MaxSompi + 1,
|
|
*subnetworkid.SubnetworkIDNative,
|
|
nil,
|
|
nil,
|
|
ruleError(ErrBadTxOutValue, "")},
|
|
{"too much sompi in total outputs", 1, 2, util.MaxSompi - 1,
|
|
*subnetworkid.SubnetworkIDNative,
|
|
nil,
|
|
nil,
|
|
ruleError(ErrBadTxOutValue, "")},
|
|
{"duplicate inputs", 2, 1, 1,
|
|
*subnetworkid.SubnetworkIDNative,
|
|
nil,
|
|
func(tx *wire.MsgTx) { tx.TxIn[1].PreviousOutpoint.Index = 0 },
|
|
ruleError(ErrDuplicateTxInputs, "")},
|
|
{"1 input coinbase",
|
|
1,
|
|
1,
|
|
1,
|
|
*subnetworkid.SubnetworkIDNative,
|
|
&txSubnetworkData{subnetworkid.SubnetworkIDCoinbase, 0, nil},
|
|
nil,
|
|
nil},
|
|
{"no inputs coinbase",
|
|
0,
|
|
1,
|
|
1,
|
|
*subnetworkid.SubnetworkIDNative,
|
|
&txSubnetworkData{subnetworkid.SubnetworkIDCoinbase, 0, nil},
|
|
nil,
|
|
nil},
|
|
{"too long payload coinbase",
|
|
1,
|
|
1,
|
|
1,
|
|
*subnetworkid.SubnetworkIDNative,
|
|
&txSubnetworkData{subnetworkid.SubnetworkIDCoinbase, 0, make([]byte, MaxCoinbasePayloadLen+1)},
|
|
nil,
|
|
ruleError(ErrBadCoinbasePayloadLen, "")},
|
|
{"non-zero gas in Kaspa", 1, 1, 0,
|
|
*subnetworkid.SubnetworkIDNative,
|
|
&txSubnetworkData{subnetworkid.SubnetworkIDNative, 1, []byte{}},
|
|
nil,
|
|
ruleError(ErrInvalidGas, "")},
|
|
{"non-zero gas in subnetwork registry", 1, 1, 0,
|
|
*subnetworkid.SubnetworkIDNative,
|
|
&txSubnetworkData{subnetworkid.SubnetworkIDNative, 1, []byte{}},
|
|
nil,
|
|
ruleError(ErrInvalidGas, "")},
|
|
{"non-zero payload in Kaspa", 1, 1, 0,
|
|
*subnetworkid.SubnetworkIDNative,
|
|
&txSubnetworkData{subnetworkid.SubnetworkIDNative, 0, []byte{1}},
|
|
nil,
|
|
ruleError(ErrInvalidPayload, "")},
|
|
{"payload in subnetwork registry isn't 8 bytes", 1, 1, 0,
|
|
*subnetworkid.SubnetworkIDNative,
|
|
&txSubnetworkData{subnetworkid.SubnetworkIDNative, 0, []byte{1, 2, 3, 4, 5, 6, 7}},
|
|
nil,
|
|
ruleError(ErrInvalidPayload, "")},
|
|
{"payload in other subnetwork isn't 0 bytes", 1, 1, 0,
|
|
subnetworkid.SubnetworkID{123},
|
|
&txSubnetworkData{&subnetworkid.SubnetworkID{234}, 0, []byte{1}},
|
|
nil,
|
|
ruleError(ErrInvalidPayload, "")},
|
|
{"invalid payload hash", 1, 1, 0,
|
|
subnetworkid.SubnetworkID{123},
|
|
&txSubnetworkData{&subnetworkid.SubnetworkID{123}, 0, []byte{1}},
|
|
func(tx *wire.MsgTx) {
|
|
tx.PayloadHash = &daghash.Hash{}
|
|
},
|
|
ruleError(ErrInvalidPayloadHash, "")},
|
|
{"invalid payload hash in native subnetwork", 1, 1, 0,
|
|
*subnetworkid.SubnetworkIDNative,
|
|
nil,
|
|
func(tx *wire.MsgTx) {
|
|
tx.PayloadHash = daghash.DoubleHashP(tx.Payload)
|
|
},
|
|
ruleError(ErrInvalidPayloadHash, "")},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
tx := createTxForTest(test.numInputs, test.numOutputs, test.outputValue, test.txSubnetworkData)
|
|
|
|
if test.extraModificationsFunc != nil {
|
|
test.extraModificationsFunc(tx)
|
|
}
|
|
|
|
err := CheckTransactionSanity(util.NewTx(tx), &test.nodeSubnetworkID)
|
|
if e := checkRuleError(err, test.expectedErr); e != nil {
|
|
t.Errorf("TestCheckTransactionSanity: '%s': %v", test.name, e)
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
|
|
// Block100000 defines block 100,000 of the block DAG. It is used to
|
|
// test Block operations.
|
|
var Block100000 = wire.MsgBlock{
|
|
Header: wire.BlockHeader{
|
|
Version: 0x10000000,
|
|
ParentHashes: []*daghash.Hash{
|
|
{
|
|
0x16, 0x5e, 0x38, 0xe8, 0xb3, 0x91, 0x45, 0x95,
|
|
0xd9, 0xc6, 0x41, 0xf3, 0xb8, 0xee, 0xc2, 0xf3,
|
|
0x46, 0x11, 0x89, 0x6b, 0x82, 0x1a, 0x68, 0x3b,
|
|
0x7a, 0x4e, 0xde, 0xfe, 0x2c, 0x00, 0x00, 0x00,
|
|
},
|
|
{
|
|
0x4b, 0xb0, 0x75, 0x35, 0xdf, 0xd5, 0x8e, 0x0b,
|
|
0x3c, 0xd6, 0x4f, 0xd7, 0x15, 0x52, 0x80, 0x87,
|
|
0x2a, 0x04, 0x71, 0xbc, 0xf8, 0x30, 0x95, 0x52,
|
|
0x6a, 0xce, 0x0e, 0x38, 0xc6, 0x00, 0x00, 0x00,
|
|
},
|
|
},
|
|
HashMerkleRoot: &daghash.Hash{
|
|
0x32, 0x30, 0x46, 0x39, 0x5e, 0x27, 0x6d, 0x5a,
|
|
0xc9, 0x64, 0x16, 0x29, 0x5b, 0xa4, 0x5a, 0xf3,
|
|
0xc0, 0xfc, 0x1a, 0xa9, 0xcb, 0x2a, 0xd2, 0x9f,
|
|
0xbe, 0x07, 0x0c, 0x47, 0xc9, 0x84, 0x39, 0x15,
|
|
},
|
|
AcceptedIDMerkleRoot: &daghash.Hash{
|
|
0x8a, 0xb7, 0xd6, 0x73, 0x1b, 0xe6, 0xc5, 0xd3,
|
|
0x5d, 0x4e, 0x2c, 0xc9, 0x57, 0x88, 0x30, 0x65,
|
|
0x81, 0xb8, 0xa0, 0x68, 0x77, 0xc4, 0x02, 0x1e,
|
|
0x3c, 0xb1, 0x16, 0x8f, 0x5f, 0x6b, 0x45, 0x87,
|
|
},
|
|
UTXOCommitment: &daghash.ZeroHash,
|
|
Timestamp: time.Unix(0x5cdac4b1, 0),
|
|
Bits: 0x207fffff,
|
|
Nonce: 0x00000001,
|
|
},
|
|
Transactions: []*wire.MsgTx{
|
|
{
|
|
Version: 1,
|
|
TxIn: []*wire.TxIn{
|
|
{
|
|
PreviousOutpoint: wire.Outpoint{
|
|
TxID: daghash.TxID{
|
|
0x9b, 0x22, 0x59, 0x44, 0x66, 0xf0, 0xbe, 0x50,
|
|
0x7c, 0x1c, 0x8a, 0xf6, 0x06, 0x27, 0xe6, 0x33,
|
|
0x38, 0x7e, 0xd1, 0xd5, 0x8c, 0x42, 0x59, 0x1a,
|
|
0x31, 0xac, 0x9a, 0xa6, 0x2e, 0xd5, 0x2b, 0x0f,
|
|
},
|
|
Index: 0xffffffff,
|
|
},
|
|
SignatureScript: nil,
|
|
Sequence: math.MaxUint64,
|
|
},
|
|
},
|
|
TxOut: []*wire.TxOut{
|
|
{
|
|
Value: 0x12a05f200, // 5000000000
|
|
ScriptPubKey: []byte{
|
|
0xa9, 0x14, 0xda, 0x17, 0x45, 0xe9, 0xb5, 0x49,
|
|
0xbd, 0x0b, 0xfa, 0x1a, 0x56, 0x99, 0x71, 0xc7,
|
|
0x7e, 0xba, 0x30, 0xcd, 0x5a, 0x4b, 0x87,
|
|
},
|
|
},
|
|
},
|
|
LockTime: 0,
|
|
SubnetworkID: *subnetworkid.SubnetworkIDCoinbase,
|
|
Payload: []byte{0x00},
|
|
PayloadHash: &daghash.Hash{
|
|
0x14, 0x06, 0xe0, 0x58, 0x81, 0xe2, 0x99, 0x36,
|
|
0x77, 0x66, 0xd3, 0x13, 0xe2, 0x6c, 0x05, 0x56,
|
|
0x4e, 0xc9, 0x1b, 0xf7, 0x21, 0xd3, 0x17, 0x26,
|
|
0xbd, 0x6e, 0x46, 0xe6, 0x06, 0x89, 0x53, 0x9a,
|
|
},
|
|
},
|
|
{
|
|
Version: 1,
|
|
TxIn: []*wire.TxIn{
|
|
{
|
|
PreviousOutpoint: wire.Outpoint{
|
|
TxID: daghash.TxID{
|
|
0x16, 0x5e, 0x38, 0xe8, 0xb3, 0x91, 0x45, 0x95,
|
|
0xd9, 0xc6, 0x41, 0xf3, 0xb8, 0xee, 0xc2, 0xf3,
|
|
0x46, 0x11, 0x89, 0x6b, 0x82, 0x1a, 0x68, 0x3b,
|
|
0x7a, 0x4e, 0xde, 0xfe, 0x2c, 0x00, 0x00, 0x00,
|
|
},
|
|
Index: 0xffffffff,
|
|
},
|
|
Sequence: math.MaxUint64,
|
|
},
|
|
{
|
|
PreviousOutpoint: wire.Outpoint{
|
|
TxID: daghash.TxID{
|
|
0x4b, 0xb0, 0x75, 0x35, 0xdf, 0xd5, 0x8e, 0x0b,
|
|
0x3c, 0xd6, 0x4f, 0xd7, 0x15, 0x52, 0x80, 0x87,
|
|
0x2a, 0x04, 0x71, 0xbc, 0xf8, 0x30, 0x95, 0x52,
|
|
0x6a, 0xce, 0x0e, 0x38, 0xc6, 0x00, 0x00, 0x00,
|
|
},
|
|
Index: 0xffffffff,
|
|
},
|
|
Sequence: math.MaxUint64,
|
|
},
|
|
},
|
|
SubnetworkID: *subnetworkid.SubnetworkIDNative,
|
|
},
|
|
{
|
|
Version: 1,
|
|
TxIn: []*wire.TxIn{
|
|
{
|
|
PreviousOutpoint: wire.Outpoint{
|
|
TxID: daghash.TxID([32]byte{
|
|
0x03, 0x2e, 0x38, 0xe9, 0xc0, 0xa8, 0x4c, 0x60,
|
|
0x46, 0xd6, 0x87, 0xd1, 0x05, 0x56, 0xdc, 0xac,
|
|
0xc4, 0x1d, 0x27, 0x5e, 0xc5, 0x5f, 0xc0, 0x07,
|
|
0x79, 0xac, 0x88, 0xfd, 0xf3, 0x57, 0xa1, 0x87,
|
|
}), // 87a157f3fd88ac7907c05fc55e271dc4acdc5605d187d646604ca8c0e9382e03
|
|
Index: 0,
|
|
},
|
|
SignatureScript: []byte{
|
|
0x49, // OP_DATA_73
|
|
0x30, 0x46, 0x02, 0x21, 0x00, 0xc3, 0x52, 0xd3,
|
|
0xdd, 0x99, 0x3a, 0x98, 0x1b, 0xeb, 0xa4, 0xa6,
|
|
0x3a, 0xd1, 0x5c, 0x20, 0x92, 0x75, 0xca, 0x94,
|
|
0x70, 0xab, 0xfc, 0xd5, 0x7d, 0xa9, 0x3b, 0x58,
|
|
0xe4, 0xeb, 0x5d, 0xce, 0x82, 0x02, 0x21, 0x00,
|
|
0x84, 0x07, 0x92, 0xbc, 0x1f, 0x45, 0x60, 0x62,
|
|
0x81, 0x9f, 0x15, 0xd3, 0x3e, 0xe7, 0x05, 0x5c,
|
|
0xf7, 0xb5, 0xee, 0x1a, 0xf1, 0xeb, 0xcc, 0x60,
|
|
0x28, 0xd9, 0xcd, 0xb1, 0xc3, 0xaf, 0x77, 0x48,
|
|
0x01, // 73-byte signature
|
|
0x41, // OP_DATA_65
|
|
0x04, 0xf4, 0x6d, 0xb5, 0xe9, 0xd6, 0x1a, 0x9d,
|
|
0xc2, 0x7b, 0x8d, 0x64, 0xad, 0x23, 0xe7, 0x38,
|
|
0x3a, 0x4e, 0x6c, 0xa1, 0x64, 0x59, 0x3c, 0x25,
|
|
0x27, 0xc0, 0x38, 0xc0, 0x85, 0x7e, 0xb6, 0x7e,
|
|
0xe8, 0xe8, 0x25, 0xdc, 0xa6, 0x50, 0x46, 0xb8,
|
|
0x2c, 0x93, 0x31, 0x58, 0x6c, 0x82, 0xe0, 0xfd,
|
|
0x1f, 0x63, 0x3f, 0x25, 0xf8, 0x7c, 0x16, 0x1b,
|
|
0xc6, 0xf8, 0xa6, 0x30, 0x12, 0x1d, 0xf2, 0xb3,
|
|
0xd3, // 65-byte pubkey
|
|
},
|
|
Sequence: math.MaxUint64,
|
|
},
|
|
},
|
|
TxOut: []*wire.TxOut{
|
|
{
|
|
Value: 0x2123e300, // 556000000
|
|
ScriptPubKey: []byte{
|
|
0x76, // OP_DUP
|
|
0xa9, // OP_HASH160
|
|
0x14, // OP_DATA_20
|
|
0xc3, 0x98, 0xef, 0xa9, 0xc3, 0x92, 0xba, 0x60,
|
|
0x13, 0xc5, 0xe0, 0x4e, 0xe7, 0x29, 0x75, 0x5e,
|
|
0xf7, 0xf5, 0x8b, 0x32,
|
|
0x88, // OP_EQUALVERIFY
|
|
0xac, // OP_CHECKSIG
|
|
},
|
|
},
|
|
{
|
|
Value: 0x108e20f00, // 4444000000
|
|
ScriptPubKey: []byte{
|
|
0x76, // OP_DUP
|
|
0xa9, // OP_HASH160
|
|
0x14, // OP_DATA_20
|
|
0x94, 0x8c, 0x76, 0x5a, 0x69, 0x14, 0xd4, 0x3f,
|
|
0x2a, 0x7a, 0xc1, 0x77, 0xda, 0x2c, 0x2f, 0x6b,
|
|
0x52, 0xde, 0x3d, 0x7c,
|
|
0x88, // OP_EQUALVERIFY
|
|
0xac, // OP_CHECKSIG
|
|
},
|
|
},
|
|
},
|
|
LockTime: 0,
|
|
SubnetworkID: *subnetworkid.SubnetworkIDNative,
|
|
},
|
|
{
|
|
Version: 1,
|
|
TxIn: []*wire.TxIn{
|
|
{
|
|
PreviousOutpoint: wire.Outpoint{
|
|
TxID: daghash.TxID([32]byte{
|
|
0xc3, 0x3e, 0xbf, 0xf2, 0xa7, 0x09, 0xf1, 0x3d,
|
|
0x9f, 0x9a, 0x75, 0x69, 0xab, 0x16, 0xa3, 0x27,
|
|
0x86, 0xaf, 0x7d, 0x7e, 0x2d, 0xe0, 0x92, 0x65,
|
|
0xe4, 0x1c, 0x61, 0xd0, 0x78, 0x29, 0x4e, 0xcf,
|
|
}), // cf4e2978d0611ce46592e02d7e7daf8627a316ab69759a9f3df109a7f2bf3ec3
|
|
Index: 1,
|
|
},
|
|
SignatureScript: []byte{
|
|
0x47, // OP_DATA_71
|
|
0x30, 0x44, 0x02, 0x20, 0x03, 0x2d, 0x30, 0xdf,
|
|
0x5e, 0xe6, 0xf5, 0x7f, 0xa4, 0x6c, 0xdd, 0xb5,
|
|
0xeb, 0x8d, 0x0d, 0x9f, 0xe8, 0xde, 0x6b, 0x34,
|
|
0x2d, 0x27, 0x94, 0x2a, 0xe9, 0x0a, 0x32, 0x31,
|
|
0xe0, 0xba, 0x33, 0x3e, 0x02, 0x20, 0x3d, 0xee,
|
|
0xe8, 0x06, 0x0f, 0xdc, 0x70, 0x23, 0x0a, 0x7f,
|
|
0x5b, 0x4a, 0xd7, 0xd7, 0xbc, 0x3e, 0x62, 0x8c,
|
|
0xbe, 0x21, 0x9a, 0x88, 0x6b, 0x84, 0x26, 0x9e,
|
|
0xae, 0xb8, 0x1e, 0x26, 0xb4, 0xfe, 0x01,
|
|
0x41, // OP_DATA_65
|
|
0x04, 0xae, 0x31, 0xc3, 0x1b, 0xf9, 0x12, 0x78,
|
|
0xd9, 0x9b, 0x83, 0x77, 0xa3, 0x5b, 0xbc, 0xe5,
|
|
0xb2, 0x7d, 0x9f, 0xff, 0x15, 0x45, 0x68, 0x39,
|
|
0xe9, 0x19, 0x45, 0x3f, 0xc7, 0xb3, 0xf7, 0x21,
|
|
0xf0, 0xba, 0x40, 0x3f, 0xf9, 0x6c, 0x9d, 0xee,
|
|
0xb6, 0x80, 0xe5, 0xfd, 0x34, 0x1c, 0x0f, 0xc3,
|
|
0xa7, 0xb9, 0x0d, 0xa4, 0x63, 0x1e, 0xe3, 0x95,
|
|
0x60, 0x63, 0x9d, 0xb4, 0x62, 0xe9, 0xcb, 0x85,
|
|
0x0f, // 65-byte pubkey
|
|
},
|
|
Sequence: math.MaxUint64,
|
|
},
|
|
},
|
|
TxOut: []*wire.TxOut{
|
|
{
|
|
Value: 0xf4240, // 1000000
|
|
ScriptPubKey: []byte{
|
|
0x76, // OP_DUP
|
|
0xa9, // OP_HASH160
|
|
0x14, // OP_DATA_20
|
|
0xb0, 0xdc, 0xbf, 0x97, 0xea, 0xbf, 0x44, 0x04,
|
|
0xe3, 0x1d, 0x95, 0x24, 0x77, 0xce, 0x82, 0x2d,
|
|
0xad, 0xbe, 0x7e, 0x10,
|
|
0x88, // OP_EQUALVERIFY
|
|
0xac, // OP_CHECKSIG
|
|
},
|
|
},
|
|
{
|
|
Value: 0x11d260c0, // 299000000
|
|
ScriptPubKey: []byte{
|
|
0x76, // OP_DUP
|
|
0xa9, // OP_HASH160
|
|
0x14, // OP_DATA_20
|
|
0x6b, 0x12, 0x81, 0xee, 0xc2, 0x5a, 0xb4, 0xe1,
|
|
0xe0, 0x79, 0x3f, 0xf4, 0xe0, 0x8a, 0xb1, 0xab,
|
|
0xb3, 0x40, 0x9c, 0xd9,
|
|
0x88, // OP_EQUALVERIFY
|
|
0xac, // OP_CHECKSIG
|
|
},
|
|
},
|
|
},
|
|
LockTime: 0,
|
|
SubnetworkID: *subnetworkid.SubnetworkIDNative,
|
|
},
|
|
{
|
|
Version: 1,
|
|
TxIn: []*wire.TxIn{
|
|
{
|
|
PreviousOutpoint: wire.Outpoint{
|
|
TxID: daghash.TxID([32]byte{
|
|
0x0b, 0x60, 0x72, 0xb3, 0x86, 0xd4, 0xa7, 0x73,
|
|
0x23, 0x52, 0x37, 0xf6, 0x4c, 0x11, 0x26, 0xac,
|
|
0x3b, 0x24, 0x0c, 0x84, 0xb9, 0x17, 0xa3, 0x90,
|
|
0x9b, 0xa1, 0xc4, 0x3d, 0xed, 0x5f, 0x51, 0xf4,
|
|
}), // f4515fed3dc4a19b90a317b9840c243bac26114cf637522373a7d486b372600b
|
|
Index: 0,
|
|
},
|
|
SignatureScript: []byte{
|
|
0x49, // OP_DATA_73
|
|
0x30, 0x46, 0x02, 0x21, 0x00, 0xbb, 0x1a, 0xd2,
|
|
0x6d, 0xf9, 0x30, 0xa5, 0x1c, 0xce, 0x11, 0x0c,
|
|
0xf4, 0x4f, 0x7a, 0x48, 0xc3, 0xc5, 0x61, 0xfd,
|
|
0x97, 0x75, 0x00, 0xb1, 0xae, 0x5d, 0x6b, 0x6f,
|
|
0xd1, 0x3d, 0x0b, 0x3f, 0x4a, 0x02, 0x21, 0x00,
|
|
0xc5, 0xb4, 0x29, 0x51, 0xac, 0xed, 0xff, 0x14,
|
|
0xab, 0xba, 0x27, 0x36, 0xfd, 0x57, 0x4b, 0xdb,
|
|
0x46, 0x5f, 0x3e, 0x6f, 0x8d, 0xa1, 0x2e, 0x2c,
|
|
0x53, 0x03, 0x95, 0x4a, 0xca, 0x7f, 0x78, 0xf3,
|
|
0x01, // 73-byte signature
|
|
0x41, // OP_DATA_65
|
|
0x04, 0xa7, 0x13, 0x5b, 0xfe, 0x82, 0x4c, 0x97,
|
|
0xec, 0xc0, 0x1e, 0xc7, 0xd7, 0xe3, 0x36, 0x18,
|
|
0x5c, 0x81, 0xe2, 0xaa, 0x2c, 0x41, 0xab, 0x17,
|
|
0x54, 0x07, 0xc0, 0x94, 0x84, 0xce, 0x96, 0x94,
|
|
0xb4, 0x49, 0x53, 0xfc, 0xb7, 0x51, 0x20, 0x65,
|
|
0x64, 0xa9, 0xc2, 0x4d, 0xd0, 0x94, 0xd4, 0x2f,
|
|
0xdb, 0xfd, 0xd5, 0xaa, 0xd3, 0xe0, 0x63, 0xce,
|
|
0x6a, 0xf4, 0xcf, 0xaa, 0xea, 0x4e, 0xa1, 0x4f,
|
|
0xbb, // 65-byte pubkey
|
|
},
|
|
Sequence: math.MaxUint64,
|
|
},
|
|
},
|
|
TxOut: []*wire.TxOut{
|
|
{
|
|
Value: 0xf4240, // 1000000
|
|
ScriptPubKey: []byte{
|
|
0x76, // OP_DUP
|
|
0xa9, // OP_HASH160
|
|
0x14, // OP_DATA_20
|
|
0x39, 0xaa, 0x3d, 0x56, 0x9e, 0x06, 0xa1, 0xd7,
|
|
0x92, 0x6d, 0xc4, 0xbe, 0x11, 0x93, 0xc9, 0x9b,
|
|
0xf2, 0xeb, 0x9e, 0xe0,
|
|
0x88, // OP_EQUALVERIFY
|
|
0xac, // OP_CHECKSIG
|
|
},
|
|
},
|
|
},
|
|
LockTime: 0,
|
|
SubnetworkID: *subnetworkid.SubnetworkIDNative,
|
|
},
|
|
},
|
|
}
|
|
|
|
// BlockWithWrongTxOrder defines invalid block 100,000 of the block DAG.
|
|
var BlockWithWrongTxOrder = wire.MsgBlock{
|
|
Header: wire.BlockHeader{
|
|
Version: 1,
|
|
ParentHashes: []*daghash.Hash{
|
|
{
|
|
0x16, 0x5e, 0x38, 0xe8, 0xb3, 0x91, 0x45, 0x95,
|
|
0xd9, 0xc6, 0x41, 0xf3, 0xb8, 0xee, 0xc2, 0xf3,
|
|
0x46, 0x11, 0x89, 0x6b, 0x82, 0x1a, 0x68, 0x3b,
|
|
0x7a, 0x4e, 0xde, 0xfe, 0x2c, 0x00, 0x00, 0x00,
|
|
},
|
|
{
|
|
0x4b, 0xb0, 0x75, 0x35, 0xdf, 0xd5, 0x8e, 0x0b,
|
|
0x3c, 0xd6, 0x4f, 0xd7, 0x15, 0x52, 0x80, 0x87,
|
|
0x2a, 0x04, 0x71, 0xbc, 0xf8, 0x30, 0x95, 0x52,
|
|
0x6a, 0xce, 0x0e, 0x38, 0xc6, 0x00, 0x00, 0x00,
|
|
},
|
|
},
|
|
HashMerkleRoot: &daghash.Hash{
|
|
0xac, 0xa4, 0x21, 0xe1, 0xa6, 0xc3, 0xbe, 0x5d,
|
|
0x52, 0x66, 0xf3, 0x0b, 0x21, 0x87, 0xbc, 0xf3,
|
|
0xf3, 0x2d, 0xd1, 0x05, 0x64, 0xb5, 0x16, 0x76,
|
|
0xe4, 0x66, 0x7d, 0x51, 0x53, 0x18, 0x6d, 0xb1,
|
|
},
|
|
AcceptedIDMerkleRoot: &daghash.Hash{
|
|
0xa0, 0x69, 0x2d, 0x16, 0xb5, 0xd7, 0xe4, 0xf3,
|
|
0xcd, 0xc7, 0xc9, 0xaf, 0xfb, 0xd2, 0x1b, 0x85,
|
|
0x0b, 0x79, 0xf5, 0x29, 0x6d, 0x1c, 0xaa, 0x90,
|
|
0x2f, 0x01, 0xd4, 0x83, 0x9b, 0x2a, 0x04, 0x5e,
|
|
},
|
|
UTXOCommitment: &daghash.Hash{
|
|
0x00, 0x69, 0x2d, 0x16, 0xb5, 0xd7, 0xe4, 0xf3,
|
|
0xcd, 0xc7, 0xc9, 0xaf, 0xfb, 0xd2, 0x1b, 0x85,
|
|
0x0b, 0x79, 0xf5, 0x29, 0x6d, 0x1c, 0xaa, 0x90,
|
|
0x2f, 0x01, 0xd4, 0x83, 0x9b, 0x2a, 0x04, 0x5e,
|
|
},
|
|
Timestamp: time.Unix(0x5cd16eaa, 0),
|
|
Bits: 0x207fffff,
|
|
Nonce: 0x0,
|
|
},
|
|
Transactions: []*wire.MsgTx{
|
|
{
|
|
Version: 1,
|
|
TxIn: []*wire.TxIn{
|
|
{
|
|
PreviousOutpoint: wire.Outpoint{
|
|
TxID: daghash.TxID{
|
|
0x9b, 0x22, 0x59, 0x44, 0x66, 0xf0, 0xbe, 0x50,
|
|
0x7c, 0x1c, 0x8a, 0xf6, 0x06, 0x27, 0xe6, 0x33,
|
|
0x38, 0x7e, 0xd1, 0xd5, 0x8c, 0x42, 0x59, 0x1a,
|
|
0x31, 0xac, 0x9a, 0xa6, 0x2e, 0xd5, 0x2b, 0x0f,
|
|
},
|
|
Index: 0xffffffff,
|
|
},
|
|
SignatureScript: nil,
|
|
Sequence: math.MaxUint64,
|
|
},
|
|
},
|
|
TxOut: []*wire.TxOut{
|
|
{
|
|
Value: 0x12a05f200, // 5000000000
|
|
ScriptPubKey: []byte{
|
|
0xa9, 0x14, 0xda, 0x17, 0x45, 0xe9, 0xb5, 0x49,
|
|
0xbd, 0x0b, 0xfa, 0x1a, 0x56, 0x99, 0x71, 0xc7,
|
|
0x7e, 0xba, 0x30, 0xcd, 0x5a, 0x4b, 0x87,
|
|
},
|
|
},
|
|
},
|
|
LockTime: 0,
|
|
SubnetworkID: *subnetworkid.SubnetworkIDCoinbase,
|
|
Payload: []byte{0x00},
|
|
PayloadHash: &daghash.Hash{
|
|
0x14, 0x06, 0xe0, 0x58, 0x81, 0xe2, 0x99, 0x36,
|
|
0x77, 0x66, 0xd3, 0x13, 0xe2, 0x6c, 0x05, 0x56,
|
|
0x4e, 0xc9, 0x1b, 0xf7, 0x21, 0xd3, 0x17, 0x26,
|
|
0xbd, 0x6e, 0x46, 0xe6, 0x06, 0x89, 0x53, 0x9a,
|
|
},
|
|
},
|
|
{
|
|
Version: 1,
|
|
TxIn: []*wire.TxIn{
|
|
{
|
|
PreviousOutpoint: wire.Outpoint{
|
|
TxID: daghash.TxID{
|
|
0x16, 0x5e, 0x38, 0xe8, 0xb3, 0x91, 0x45, 0x95,
|
|
0xd9, 0xc6, 0x41, 0xf3, 0xb8, 0xee, 0xc2, 0xf3,
|
|
0x46, 0x11, 0x89, 0x6b, 0x82, 0x1a, 0x68, 0x3b,
|
|
0x7a, 0x4e, 0xde, 0xfe, 0x2c, 0x00, 0x00, 0x00,
|
|
},
|
|
Index: 0xffffffff,
|
|
},
|
|
Sequence: math.MaxUint64,
|
|
},
|
|
{
|
|
PreviousOutpoint: wire.Outpoint{
|
|
TxID: daghash.TxID{
|
|
0x4b, 0xb0, 0x75, 0x35, 0xdf, 0xd5, 0x8e, 0x0b,
|
|
0x3c, 0xd6, 0x4f, 0xd7, 0x15, 0x52, 0x80, 0x87,
|
|
0x2a, 0x04, 0x71, 0xbc, 0xf8, 0x30, 0x95, 0x52,
|
|
0x6a, 0xce, 0x0e, 0x38, 0xc6, 0x00, 0x00, 0x00,
|
|
},
|
|
Index: 0xffffffff,
|
|
},
|
|
Sequence: math.MaxUint64,
|
|
},
|
|
},
|
|
SubnetworkID: *subnetworkid.SubnetworkIDNative,
|
|
},
|
|
{
|
|
Version: 1,
|
|
TxIn: []*wire.TxIn{
|
|
{
|
|
PreviousOutpoint: wire.Outpoint{
|
|
TxID: daghash.TxID([32]byte{
|
|
0x03, 0x2e, 0x38, 0xe9, 0xc0, 0xa8, 0x4c, 0x60,
|
|
0x46, 0xd6, 0x87, 0xd1, 0x05, 0x56, 0xdc, 0xac,
|
|
0xc4, 0x1d, 0x27, 0x5e, 0xc5, 0x5f, 0xc0, 0x07,
|
|
0x79, 0xac, 0x88, 0xfd, 0xf3, 0x57, 0xa1, 0x87,
|
|
}), // 87a157f3fd88ac7907c05fc55e271dc4acdc5605d187d646604ca8c0e9382e03
|
|
Index: 0,
|
|
},
|
|
SignatureScript: []byte{
|
|
0x49, // OP_DATA_73
|
|
0x30, 0x46, 0x02, 0x21, 0x00, 0xc3, 0x52, 0xd3,
|
|
0xdd, 0x99, 0x3a, 0x98, 0x1b, 0xeb, 0xa4, 0xa6,
|
|
0x3a, 0xd1, 0x5c, 0x20, 0x92, 0x75, 0xca, 0x94,
|
|
0x70, 0xab, 0xfc, 0xd5, 0x7d, 0xa9, 0x3b, 0x58,
|
|
0xe4, 0xeb, 0x5d, 0xce, 0x82, 0x02, 0x21, 0x00,
|
|
0x84, 0x07, 0x92, 0xbc, 0x1f, 0x45, 0x60, 0x62,
|
|
0x81, 0x9f, 0x15, 0xd3, 0x3e, 0xe7, 0x05, 0x5c,
|
|
0xf7, 0xb5, 0xee, 0x1a, 0xf1, 0xeb, 0xcc, 0x60,
|
|
0x28, 0xd9, 0xcd, 0xb1, 0xc3, 0xaf, 0x77, 0x48,
|
|
0x01, // 73-byte signature
|
|
0x41, // OP_DATA_65
|
|
0x04, 0xf4, 0x6d, 0xb5, 0xe9, 0xd6, 0x1a, 0x9d,
|
|
0xc2, 0x7b, 0x8d, 0x64, 0xad, 0x23, 0xe7, 0x38,
|
|
0x3a, 0x4e, 0x6c, 0xa1, 0x64, 0x59, 0x3c, 0x25,
|
|
0x27, 0xc0, 0x38, 0xc0, 0x85, 0x7e, 0xb6, 0x7e,
|
|
0xe8, 0xe8, 0x25, 0xdc, 0xa6, 0x50, 0x46, 0xb8,
|
|
0x2c, 0x93, 0x31, 0x58, 0x6c, 0x82, 0xe0, 0xfd,
|
|
0x1f, 0x63, 0x3f, 0x25, 0xf8, 0x7c, 0x16, 0x1b,
|
|
0xc6, 0xf8, 0xa6, 0x30, 0x12, 0x1d, 0xf2, 0xb3,
|
|
0xd3, // 65-byte pubkey
|
|
},
|
|
Sequence: math.MaxUint64,
|
|
},
|
|
},
|
|
TxOut: []*wire.TxOut{
|
|
{
|
|
Value: 0x2123e300, // 556000000
|
|
ScriptPubKey: []byte{
|
|
0x76, // OP_DUP
|
|
0xa9, // OP_HASH160
|
|
0x14, // OP_DATA_20
|
|
0xc3, 0x98, 0xef, 0xa9, 0xc3, 0x92, 0xba, 0x60,
|
|
0x13, 0xc5, 0xe0, 0x4e, 0xe7, 0x29, 0x75, 0x5e,
|
|
0xf7, 0xf5, 0x8b, 0x32,
|
|
0x88, // OP_EQUALVERIFY
|
|
0xac, // OP_CHECKSIG
|
|
},
|
|
},
|
|
{
|
|
Value: 0x108e20f00, // 4444000000
|
|
ScriptPubKey: []byte{
|
|
0x76, // OP_DUP
|
|
0xa9, // OP_HASH160
|
|
0x14, // OP_DATA_20
|
|
0x94, 0x8c, 0x76, 0x5a, 0x69, 0x14, 0xd4, 0x3f,
|
|
0x2a, 0x7a, 0xc1, 0x77, 0xda, 0x2c, 0x2f, 0x6b,
|
|
0x52, 0xde, 0x3d, 0x7c,
|
|
0x88, // OP_EQUALVERIFY
|
|
0xac, // OP_CHECKSIG
|
|
},
|
|
},
|
|
},
|
|
LockTime: 0,
|
|
SubnetworkID: subnetworkid.SubnetworkID{11},
|
|
Payload: []byte{},
|
|
PayloadHash: daghash.DoubleHashP([]byte{}),
|
|
},
|
|
{
|
|
Version: 1,
|
|
TxIn: []*wire.TxIn{
|
|
{
|
|
PreviousOutpoint: wire.Outpoint{
|
|
TxID: daghash.TxID([32]byte{
|
|
0xc3, 0x3e, 0xbf, 0xf2, 0xa7, 0x09, 0xf1, 0x3d,
|
|
0x9f, 0x9a, 0x75, 0x69, 0xab, 0x16, 0xa3, 0x27,
|
|
0x86, 0xaf, 0x7d, 0x7e, 0x2d, 0xe0, 0x92, 0x65,
|
|
0xe4, 0x1c, 0x61, 0xd0, 0x78, 0x29, 0x4e, 0xcf,
|
|
}), // cf4e2978d0611ce46592e02d7e7daf8627a316ab69759a9f3df109a7f2bf3ec3
|
|
Index: 1,
|
|
},
|
|
SignatureScript: []byte{
|
|
0x47, // OP_DATA_71
|
|
0x30, 0x44, 0x02, 0x20, 0x03, 0x2d, 0x30, 0xdf,
|
|
0x5e, 0xe6, 0xf5, 0x7f, 0xa4, 0x6c, 0xdd, 0xb5,
|
|
0xeb, 0x8d, 0x0d, 0x9f, 0xe8, 0xde, 0x6b, 0x34,
|
|
0x2d, 0x27, 0x94, 0x2a, 0xe9, 0x0a, 0x32, 0x31,
|
|
0xe0, 0xba, 0x33, 0x3e, 0x02, 0x20, 0x3d, 0xee,
|
|
0xe8, 0x06, 0x0f, 0xdc, 0x70, 0x23, 0x0a, 0x7f,
|
|
0x5b, 0x4a, 0xd7, 0xd7, 0xbc, 0x3e, 0x62, 0x8c,
|
|
0xbe, 0x21, 0x9a, 0x88, 0x6b, 0x84, 0x26, 0x9e,
|
|
0xae, 0xb8, 0x1e, 0x26, 0xb4, 0xfe, 0x01,
|
|
0x41, // OP_DATA_65
|
|
0x04, 0xae, 0x31, 0xc3, 0x1b, 0xf9, 0x12, 0x78,
|
|
0xd9, 0x9b, 0x83, 0x77, 0xa3, 0x5b, 0xbc, 0xe5,
|
|
0xb2, 0x7d, 0x9f, 0xff, 0x15, 0x45, 0x68, 0x39,
|
|
0xe9, 0x19, 0x45, 0x3f, 0xc7, 0xb3, 0xf7, 0x21,
|
|
0xf0, 0xba, 0x40, 0x3f, 0xf9, 0x6c, 0x9d, 0xee,
|
|
0xb6, 0x80, 0xe5, 0xfd, 0x34, 0x1c, 0x0f, 0xc3,
|
|
0xa7, 0xb9, 0x0d, 0xa4, 0x63, 0x1e, 0xe3, 0x95,
|
|
0x60, 0x63, 0x9d, 0xb4, 0x62, 0xe9, 0xcb, 0x85,
|
|
0x0f, // 65-byte pubkey
|
|
},
|
|
Sequence: math.MaxUint64,
|
|
},
|
|
},
|
|
TxOut: []*wire.TxOut{
|
|
{
|
|
Value: 0xf4240, // 1000000
|
|
ScriptPubKey: []byte{
|
|
0x76, // OP_DUP
|
|
0xa9, // OP_HASH160
|
|
0x14, // OP_DATA_20
|
|
0xb0, 0xdc, 0xbf, 0x97, 0xea, 0xbf, 0x44, 0x04,
|
|
0xe3, 0x1d, 0x95, 0x24, 0x77, 0xce, 0x82, 0x2d,
|
|
0xad, 0xbe, 0x7e, 0x10,
|
|
0x88, // OP_EQUALVERIFY
|
|
0xac, // OP_CHECKSIG
|
|
},
|
|
},
|
|
{
|
|
Value: 0x11d260c0, // 299000000
|
|
ScriptPubKey: []byte{
|
|
0x76, // OP_DUP
|
|
0xa9, // OP_HASH160
|
|
0x14, // OP_DATA_20
|
|
0x6b, 0x12, 0x81, 0xee, 0xc2, 0x5a, 0xb4, 0xe1,
|
|
0xe0, 0x79, 0x3f, 0xf4, 0xe0, 0x8a, 0xb1, 0xab,
|
|
0xb3, 0x40, 0x9c, 0xd9,
|
|
0x88, // OP_EQUALVERIFY
|
|
0xac, // OP_CHECKSIG
|
|
},
|
|
},
|
|
},
|
|
LockTime: 0,
|
|
SubnetworkID: *subnetworkid.SubnetworkIDNative,
|
|
},
|
|
{
|
|
Version: 1,
|
|
TxIn: []*wire.TxIn{
|
|
{
|
|
PreviousOutpoint: wire.Outpoint{
|
|
TxID: daghash.TxID([32]byte{
|
|
0x0b, 0x60, 0x72, 0xb3, 0x86, 0xd4, 0xa7, 0x73,
|
|
0x23, 0x52, 0x37, 0xf6, 0x4c, 0x11, 0x26, 0xac,
|
|
0x3b, 0x24, 0x0c, 0x84, 0xb9, 0x17, 0xa3, 0x90,
|
|
0x9b, 0xa1, 0xc4, 0x3d, 0xed, 0x5f, 0x51, 0xf4,
|
|
}), // f4515fed3dc4a19b90a317b9840c243bac26114cf637522373a7d486b372600b
|
|
Index: 0,
|
|
},
|
|
SignatureScript: []byte{
|
|
0x49, // OP_DATA_73
|
|
0x30, 0x46, 0x02, 0x21, 0x00, 0xbb, 0x1a, 0xd2,
|
|
0x6d, 0xf9, 0x30, 0xa5, 0x1c, 0xce, 0x11, 0x0c,
|
|
0xf4, 0x4f, 0x7a, 0x48, 0xc3, 0xc5, 0x61, 0xfd,
|
|
0x97, 0x75, 0x00, 0xb1, 0xae, 0x5d, 0x6b, 0x6f,
|
|
0xd1, 0x3d, 0x0b, 0x3f, 0x4a, 0x02, 0x21, 0x00,
|
|
0xc5, 0xb4, 0x29, 0x51, 0xac, 0xed, 0xff, 0x14,
|
|
0xab, 0xba, 0x27, 0x36, 0xfd, 0x57, 0x4b, 0xdb,
|
|
0x46, 0x5f, 0x3e, 0x6f, 0x8d, 0xa1, 0x2e, 0x2c,
|
|
0x53, 0x03, 0x95, 0x4a, 0xca, 0x7f, 0x78, 0xf3,
|
|
0x01, // 73-byte signature
|
|
0x41, // OP_DATA_65
|
|
0x04, 0xa7, 0x13, 0x5b, 0xfe, 0x82, 0x4c, 0x97,
|
|
0xec, 0xc0, 0x1e, 0xc7, 0xd7, 0xe3, 0x36, 0x18,
|
|
0x5c, 0x81, 0xe2, 0xaa, 0x2c, 0x41, 0xab, 0x17,
|
|
0x54, 0x07, 0xc0, 0x94, 0x84, 0xce, 0x96, 0x94,
|
|
0xb4, 0x49, 0x53, 0xfc, 0xb7, 0x51, 0x20, 0x65,
|
|
0x64, 0xa9, 0xc2, 0x4d, 0xd0, 0x94, 0xd4, 0x2f,
|
|
0xdb, 0xfd, 0xd5, 0xaa, 0xd3, 0xe0, 0x63, 0xce,
|
|
0x6a, 0xf4, 0xcf, 0xaa, 0xea, 0x4e, 0xa1, 0x4f,
|
|
0xbb, // 65-byte pubkey
|
|
},
|
|
Sequence: math.MaxUint64,
|
|
},
|
|
},
|
|
TxOut: []*wire.TxOut{
|
|
{
|
|
Value: 0xf4240, // 1000000
|
|
ScriptPubKey: []byte{
|
|
0x76, // OP_DUP
|
|
0xa9, // OP_HASH160
|
|
0x14, // OP_DATA_20
|
|
0x39, 0xaa, 0x3d, 0x56, 0x9e, 0x06, 0xa1, 0xd7,
|
|
0x92, 0x6d, 0xc4, 0xbe, 0x11, 0x93, 0xc9, 0x9b,
|
|
0xf2, 0xeb, 0x9e, 0xe0,
|
|
0x88, // OP_EQUALVERIFY
|
|
0xac, // OP_CHECKSIG
|
|
},
|
|
},
|
|
},
|
|
LockTime: 0,
|
|
SubnetworkID: *subnetworkid.SubnetworkIDNative,
|
|
},
|
|
},
|
|
}
|