mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00
Merge remote-tracking branch 'origin/dev-304-change-subnetworkid-to-hash-instead-of-running-number'
This commit is contained in:
commit
1743877b66
@ -56,10 +56,13 @@ func TestMaybeAcceptBlockErrors(t *testing.T) {
|
||||
|
||||
// Add a valid block and mark it as invalid
|
||||
block1 := blocks[1]
|
||||
_, err = dag.ProcessBlock(block1, BFNone)
|
||||
isOrphan, err := dag.ProcessBlock(block1, BFNone)
|
||||
if err != nil {
|
||||
t.Fatalf("TestMaybeAcceptBlockErrors: Valid block unexpectedly returned an error: %s", err)
|
||||
}
|
||||
if isOrphan {
|
||||
t.Fatalf("TestMaybeAcceptBlockErrors: incorrectly returned block 1 is an orphan")
|
||||
}
|
||||
blockNode1 := dag.index.LookupNode(block1.Hash())
|
||||
dag.index.SetStatusFlags(blockNode1, statusValidateFailed)
|
||||
|
||||
|
@ -516,8 +516,6 @@ func (dag *BlockDAG) connectBlock(node *blockNode, block *util.Block, fastAdd bo
|
||||
}
|
||||
}
|
||||
|
||||
initialFinalityPoint := dag.lastFinalityPoint
|
||||
|
||||
var finalityPointCandidate *blockNode
|
||||
if !fastAdd {
|
||||
var err error
|
||||
@ -537,14 +535,6 @@ func (dag *BlockDAG) connectBlock(node *blockNode, block *util.Block, fastAdd bo
|
||||
dag.lastFinalityPoint = finalityPointCandidate
|
||||
}
|
||||
|
||||
// Scan all accepted transactions and collect any sub-network registry
|
||||
// transactions into subNetworkRegistryTxs. If any sub-network registry
|
||||
// transaction is not well-formed, fail the entire block.
|
||||
subNetworkRegistryTxs, err := validateAndExtractSubNetworkRegistryTxs(acceptedTxsData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Write any block status changes to DB before updating the DAG state.
|
||||
err = dag.index.flushToDB()
|
||||
if err != nil {
|
||||
@ -557,7 +547,6 @@ func (dag *BlockDAG) connectBlock(node *blockNode, block *util.Block, fastAdd bo
|
||||
state := &dagState{
|
||||
TipHashes: dag.TipHashes(),
|
||||
LastFinalityPoint: dag.lastFinalityPoint.hash,
|
||||
LastSubNetworkID: dag.lastSubNetworkID,
|
||||
}
|
||||
err := dbPutDAGState(dbTx, state)
|
||||
if err != nil {
|
||||
@ -578,22 +567,14 @@ func (dag *BlockDAG) connectBlock(node *blockNode, block *util.Block, fastAdd bo
|
||||
return err
|
||||
}
|
||||
|
||||
// Add the pending sub-network in this block to the pending sub-networks
|
||||
// collection.
|
||||
err = dbPutPendingSubNetworkTxs(dbTx, block.Hash(), subNetworkRegistryTxs)
|
||||
// Scan all accepted transactions and register any sub-network registry
|
||||
// transaction. If any sub-network registry transaction is not well-formed,
|
||||
// fail the entire block.
|
||||
err = registerSubNetworks(dbTx, acceptedTxsData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Register all pending sub-networks between the initial finality point and
|
||||
// the new one.
|
||||
if initialFinalityPoint != dag.lastFinalityPoint {
|
||||
err = dag.registerPendingSubNetworks(dbTx, initialFinalityPoint, dag.lastFinalityPoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Allow the index manager to call each of the currently active
|
||||
// optional indexes with the block being connected so they can
|
||||
// update themselves accordingly.
|
||||
@ -1603,7 +1584,6 @@ func New(config *Config) (*BlockDAG, error) {
|
||||
warningCaches: newThresholdCaches(vbNumBits),
|
||||
deploymentCaches: newThresholdCaches(dagconfig.DefinedDeployments),
|
||||
blockCount: 1,
|
||||
lastSubNetworkID: wire.SubNetworkUnreservedFirst,
|
||||
}
|
||||
|
||||
// Initialize the chain state from the passed database. When the db
|
||||
|
@ -185,10 +185,10 @@ func TestHaveBlock(t *testing.T) {
|
||||
{hash: dagconfig.SimNetParams.GenesisHash.String(), want: true},
|
||||
|
||||
// Block 3b should be present (as a second child of Block 2).
|
||||
{hash: "74e325a48f84020f3d36c07edf9cda95d93cff866ff8e8df5d2825d2ced6d28f", want: true},
|
||||
{hash: "2664223a8b2abba475ed5760433e8204806c17b60f12d826b876cccbf5f74be6", want: true},
|
||||
|
||||
// Block 100000 should be present (as an orphan).
|
||||
{hash: "566ca0e828951be69df4b45b82b4eb9b593b712a0018a382cb75790f85810be3", want: true},
|
||||
{hash: "66965d8ebcdccae2b3791f652326ef1063fa0a7e506c66f68e0c7bbb59104711", want: true},
|
||||
|
||||
// Random hashes should not be available.
|
||||
{hash: "123", want: false},
|
||||
|
@ -992,9 +992,6 @@ func (dag *BlockDAG) initDAGState() error {
|
||||
// Set the last finality point
|
||||
dag.lastFinalityPoint = dag.index.LookupNode(&state.LastFinalityPoint)
|
||||
|
||||
// Set the last sub-network ID
|
||||
dag.lastSubNetworkID = state.LastSubNetworkID
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ func ExampleBlockDAG_ProcessBlock() {
|
||||
fmt.Printf("Block accepted. Is it an orphan?: %v", isOrphan)
|
||||
|
||||
// Output:
|
||||
// Failed to process block: already have block 47c205482e0a2aa1f5503ec73ea0ffe5226f9d9357f037dcde79f75d85171634
|
||||
// Failed to process block: already have block 4acd12ea38e16dd28b067c13f677511ac0a4d9074c932223082fd444655fd9ca
|
||||
}
|
||||
|
||||
// This example demonstrates how to convert the compact "bits" in a block header
|
||||
|
@ -107,21 +107,21 @@ var block1 = wire.MsgBlock{
|
||||
Version: 1,
|
||||
ParentHashes: []daghash.Hash{
|
||||
[32]byte{ // Make go vet happy.
|
||||
0x34, 0x16, 0x17, 0x85, 0x5d, 0xf7, 0x79, 0xde,
|
||||
0xdc, 0x37, 0xf0, 0x57, 0x93, 0x9d, 0x6f, 0x22,
|
||||
0xe5, 0xff, 0xa0, 0x3e, 0xc7, 0x3e, 0x50, 0xf5,
|
||||
0xa1, 0x2a, 0x0a, 0x2e, 0x48, 0x05, 0xc2, 0x47,
|
||||
0xca, 0xd9, 0x5f, 0x65, 0x44, 0xd4, 0x2f, 0x08,
|
||||
0x23, 0x22, 0x93, 0x4c, 0x07, 0xd9, 0xa4, 0xc0,
|
||||
0x1a, 0x51, 0x77, 0xf6, 0x13, 0x7c, 0x06, 0x8b,
|
||||
0xd2, 0x6d, 0xe1, 0x38, 0xea, 0x12, 0xcd, 0x4a,
|
||||
},
|
||||
},
|
||||
MerkleRoot: daghash.Hash([32]byte{ // Make go vet happy.
|
||||
0x6c, 0x56, 0xa7, 0x7d, 0xfa, 0x18, 0x89, 0xdc,
|
||||
0x20, 0x60, 0x3f, 0x51, 0x32, 0xa8, 0xdc, 0x47,
|
||||
0x5f, 0x43, 0xb7, 0xe8, 0xae, 0x24, 0x22, 0x34,
|
||||
0x64, 0x91, 0xe7, 0xd5, 0xac, 0xc0, 0xed, 0x88,
|
||||
0x80, 0x57, 0x44, 0xf9, 0xee, 0xb7, 0x14, 0x05,
|
||||
0x8c, 0x37, 0x2e, 0x41, 0x82, 0x98, 0xcd, 0x0d,
|
||||
0xc8, 0xd1, 0xd1, 0x11, 0x9b, 0xe2, 0xc1, 0x4e,
|
||||
0x4b, 0x7c, 0x02, 0xd1, 0x11, 0xe0, 0x50, 0x11,
|
||||
}),
|
||||
Timestamp: time.Unix(0x5c238b71, 0),
|
||||
Timestamp: time.Unix(0x5c34c291, 0),
|
||||
Bits: 0x207fffff,
|
||||
Nonce: 0x00000000,
|
||||
Nonce: 0xdffffffffffffff9,
|
||||
},
|
||||
Transactions: []*wire.MsgTx{
|
||||
{
|
||||
@ -161,21 +161,21 @@ var block2 = wire.MsgBlock{
|
||||
Version: 1,
|
||||
ParentHashes: []daghash.Hash{
|
||||
[32]byte{ // Make go vet happy.
|
||||
0x69, 0xe9, 0xd1, 0xa2, 0xd0, 0x5f, 0x35, 0x39,
|
||||
0x6b, 0xa7, 0x1d, 0xeb, 0x97, 0x33, 0x7f, 0xcf,
|
||||
0xa1, 0xa8, 0xc5, 0x1f, 0x31, 0x82, 0x09, 0x62,
|
||||
0x79, 0xb3, 0xf9, 0xd6, 0x66, 0x3f, 0xd7, 0x45,
|
||||
0xf1, 0x15, 0xa7, 0xd8, 0x0e, 0xb6, 0x88, 0x25,
|
||||
0x1a, 0x9b, 0xc8, 0x6f, 0x1f, 0x71, 0x79, 0xc9,
|
||||
0x33, 0xca, 0xd7, 0x79, 0xe5, 0x40, 0x98, 0xd6,
|
||||
0x1b, 0x0b, 0x59, 0x3b, 0x98, 0x35, 0x7a, 0x1f,
|
||||
},
|
||||
},
|
||||
MerkleRoot: daghash.Hash([32]byte{ // Make go vet happy.
|
||||
0x29, 0xdc, 0xa7, 0x2b, 0x14, 0xfb, 0x5b, 0xe4,
|
||||
0x3c, 0x7c, 0x91, 0x3c, 0x54, 0x7c, 0xbe, 0x20,
|
||||
0x98, 0xe8, 0xc6, 0x01, 0x65, 0x59, 0x02, 0xa5,
|
||||
0xa2, 0xf5, 0xf1, 0x9f, 0x3b, 0x3f, 0x28, 0x3c,
|
||||
0x22, 0x71, 0xda, 0xba, 0x9d, 0x3c, 0xc8, 0xea,
|
||||
0xc7, 0x54, 0x26, 0x11, 0x31, 0x1c, 0x1a, 0x09,
|
||||
0x70, 0xde, 0x53, 0x6d, 0xaa, 0x32, 0xa6, 0x00,
|
||||
0x7a, 0x6b, 0xc4, 0x61, 0x3b, 0xc7, 0x1e, 0x13,
|
||||
}),
|
||||
Timestamp: time.Unix(0x5c238b72, 0),
|
||||
Timestamp: time.Unix(0x5c34c292, 0),
|
||||
Bits: 0x207fffff,
|
||||
Nonce: 0x2000000000000001,
|
||||
Nonce: 0xdffffffffffffffc,
|
||||
},
|
||||
Transactions: []*wire.MsgTx{
|
||||
{
|
||||
@ -213,28 +213,28 @@ var block2 = wire.MsgBlock{
|
||||
{
|
||||
PreviousOutPoint: wire.OutPoint{
|
||||
Hash: daghash.Hash{
|
||||
0x6c, 0x56, 0xa7, 0x7d, 0xfa, 0x18, 0x89, 0xdc,
|
||||
0x20, 0x60, 0x3f, 0x51, 0x32, 0xa8, 0xdc, 0x47,
|
||||
0x5f, 0x43, 0xb7, 0xe8, 0xae, 0x24, 0x22, 0x34,
|
||||
0x64, 0x91, 0xe7, 0xd5, 0xac, 0xc0, 0xed, 0x88,
|
||||
0x80, 0x57, 0x44, 0xf9, 0xee, 0xb7, 0x14, 0x05,
|
||||
0x8c, 0x37, 0x2e, 0x41, 0x82, 0x98, 0xcd, 0x0d,
|
||||
0xc8, 0xd1, 0xd1, 0x11, 0x9b, 0xe2, 0xc1, 0x4e,
|
||||
0x4b, 0x7c, 0x02, 0xd1, 0x11, 0xe0, 0x50, 0x11,
|
||||
},
|
||||
Index: 0,
|
||||
},
|
||||
SignatureScript: []byte{
|
||||
0x46, 0x30, 0x43, 0x02, 0x1f, 0x56, 0x0a, 0xfa,
|
||||
0x84, 0xc7, 0x80, 0xe1, 0x56, 0xe0, 0xec, 0x18,
|
||||
0xe7, 0xd7, 0x02, 0x87, 0x1f, 0x22, 0x62, 0xda,
|
||||
0xfa, 0x33, 0x82, 0xfc, 0x1d, 0x01, 0x7a, 0x0e,
|
||||
0xa5, 0x5f, 0x4e, 0xce, 0x02, 0x20, 0x6d, 0x1f,
|
||||
0xaf, 0xca, 0x91, 0x33, 0x8d, 0xfb, 0xb7, 0xa2,
|
||||
0x40, 0xf9, 0x4f, 0x3c, 0x04, 0xc9, 0x47, 0x29,
|
||||
0x6a, 0x7f, 0x45, 0x62, 0x0a, 0x2a, 0x7d, 0x93,
|
||||
0x7b, 0xe2, 0xc9, 0xba, 0x15, 0xb3, 0x01, 0x21,
|
||||
0x02, 0xa6, 0x73, 0x63, 0x8c, 0xb9, 0x58, 0x7c,
|
||||
0xb6, 0x8e, 0xa0, 0x8d, 0xbe, 0xf6, 0x85, 0xc6,
|
||||
0xf2, 0xd2, 0xa7, 0x51, 0xa8, 0xb3, 0xc6, 0xf2,
|
||||
0xa7, 0xe9, 0xa4, 0x99, 0x9e, 0x6e, 0x4b, 0xfa,
|
||||
0xf5,
|
||||
0x47, 0x30, 0x44, 0x02, 0x20, 0x08, 0x3e, 0x75,
|
||||
0x3e, 0x0a, 0xbc, 0x0b, 0x39, 0x06, 0xf2, 0x2c,
|
||||
0x99, 0x85, 0xf2, 0xde, 0xa7, 0x83, 0x3e, 0x6b,
|
||||
0x5a, 0x69, 0x37, 0x51, 0x4c, 0xf8, 0x40, 0x59,
|
||||
0x4c, 0x2f, 0x50, 0x1c, 0x04, 0x02, 0x20, 0x06,
|
||||
0x21, 0xd9, 0xde, 0x0c, 0x10, 0xca, 0x9d, 0xa4,
|
||||
0x5f, 0xe0, 0xfe, 0x3b, 0x33, 0x1d, 0x92, 0x6e,
|
||||
0xc4, 0x02, 0xe4, 0x3c, 0xd4, 0x3c, 0xea, 0xf8,
|
||||
0xd8, 0xe5, 0x14, 0x3f, 0x56, 0xe9, 0x5b, 0x01,
|
||||
0x21, 0x02, 0xa6, 0x73, 0x63, 0x8c, 0xb9, 0x58,
|
||||
0x7c, 0xb6, 0x8e, 0xa0, 0x8d, 0xbe, 0xf6, 0x85,
|
||||
0xc6, 0xf2, 0xd2, 0xa7, 0x51, 0xa8, 0xb3, 0xc6,
|
||||
0xf2, 0xa7, 0xe9, 0xa4, 0x99, 0x9e, 0x6e, 0x4b,
|
||||
0xfa, 0xf5,
|
||||
},
|
||||
Sequence: math.MaxUint64,
|
||||
},
|
||||
@ -262,23 +262,23 @@ var block3Tx = &wire.MsgTx{
|
||||
{
|
||||
PreviousOutPoint: wire.OutPoint{
|
||||
Hash: daghash.Hash{
|
||||
0x99, 0x30, 0x0c, 0x6e, 0xad, 0x5c, 0x9c, 0xcf,
|
||||
0xfc, 0xcb, 0x62, 0xfd, 0x39, 0xe3, 0xc1, 0x7e,
|
||||
0x87, 0x17, 0xec, 0x9e, 0x7b, 0xc7, 0x81, 0xe0,
|
||||
0x8f, 0x15, 0x85, 0xcb, 0x6d, 0x54, 0x74, 0x3e,
|
||||
0x65, 0x63, 0x9f, 0x61, 0x7c, 0xaa, 0xc1, 0x4a,
|
||||
0x96, 0x7d, 0x8a, 0xc0, 0x4b, 0x97, 0xc5, 0xf3,
|
||||
0x86, 0xbe, 0x54, 0x03, 0x26, 0x00, 0x0c, 0xc5,
|
||||
0xd8, 0xbb, 0x75, 0x96, 0x1b, 0xdb, 0xa7, 0x5b,
|
||||
},
|
||||
Index: 0,
|
||||
},
|
||||
SignatureScript: []byte{
|
||||
0x48, 0x30, 0x45, 0x02, 0x21, 0x00, 0x91, 0xa3,
|
||||
0xb4, 0x99, 0x57, 0xb2, 0x53, 0x2f, 0x7f, 0xaf,
|
||||
0xb6, 0x4d, 0x9d, 0x7b, 0x1b, 0xa2, 0x41, 0x03,
|
||||
0x1a, 0xe5, 0xfd, 0x4d, 0xe1, 0x5a, 0x7e, 0x9f,
|
||||
0xe3, 0xdd, 0x44, 0xb8, 0x62, 0x13, 0x02, 0x20,
|
||||
0x7a, 0xba, 0x9a, 0xe6, 0xa5, 0x81, 0x43, 0xb9,
|
||||
0x05, 0x66, 0xc1, 0xa3, 0x79, 0xad, 0xf0, 0xf4,
|
||||
0xb9, 0xfe, 0x28, 0x13, 0x35, 0xd6, 0x84, 0x95,
|
||||
0x08, 0xd0, 0xaa, 0x1d, 0xb7, 0x5b, 0x88, 0x4c,
|
||||
0x48, 0x30, 0x45, 0x02, 0x21, 0x00, 0x94, 0x6a,
|
||||
0x03, 0xb4, 0xab, 0xc3, 0xce, 0x5f, 0xc9, 0x85,
|
||||
0xbd, 0xb1, 0xdf, 0x94, 0x26, 0xd0, 0x27, 0x20,
|
||||
0x63, 0xdd, 0xd6, 0xd6, 0xce, 0x29, 0xb5, 0xae,
|
||||
0x91, 0x50, 0x57, 0x18, 0xc3, 0x26, 0x02, 0x20,
|
||||
0x56, 0x99, 0xa2, 0x8a, 0xbb, 0x2f, 0xfe, 0x09,
|
||||
0x11, 0x54, 0x42, 0xa7, 0xb3, 0x52, 0x35, 0xf8,
|
||||
0xa4, 0x3e, 0x01, 0x61, 0xfa, 0xb9, 0x09, 0x6d,
|
||||
0x48, 0x38, 0xa7, 0xc1, 0xfd, 0x6f, 0x9e, 0x5b,
|
||||
0x01, 0x21, 0x02, 0xa6, 0x73, 0x63, 0x8c, 0xb9,
|
||||
0x58, 0x7c, 0xb6, 0x8e, 0xa0, 0x8d, 0xbe, 0xf6,
|
||||
0x85, 0xc6, 0xf2, 0xd2, 0xa7, 0x51, 0xa8, 0xb3,
|
||||
@ -308,19 +308,19 @@ var block3 = wire.MsgBlock{
|
||||
Version: 1,
|
||||
ParentHashes: []daghash.Hash{
|
||||
[32]byte{ // Make go vet happy.
|
||||
0x96, 0x2d, 0x1d, 0x2b, 0xc2, 0xf9, 0x30, 0x43,
|
||||
0x88, 0x23, 0xdb, 0x75, 0x73, 0x43, 0xb8, 0xb6,
|
||||
0x76, 0x34, 0x42, 0x55, 0x8f, 0x44, 0x2a, 0x6f,
|
||||
0xb1, 0xac, 0x7e, 0x9b, 0x1f, 0x9f, 0x00, 0x19,
|
||||
0x41, 0x27, 0x85, 0x25, 0x0e, 0x8e, 0xdb, 0xf3,
|
||||
0xb5, 0xdd, 0xfa, 0xb9, 0x75, 0xc0, 0x4f, 0xe8,
|
||||
0x88, 0xff, 0x04, 0x08, 0xe9, 0x0a, 0x93, 0x8f,
|
||||
0x45, 0x04, 0x03, 0x73, 0xc6, 0x24, 0x08, 0x72,
|
||||
},
|
||||
},
|
||||
MerkleRoot: daghash.Hash([32]byte{ // Make go vet happy.
|
||||
0x58, 0xbd, 0x06, 0x58, 0x0a, 0xab, 0x32, 0x10,
|
||||
0x97, 0x5c, 0xc6, 0x97, 0xb0, 0xde, 0xb9, 0xe2,
|
||||
0xa6, 0x21, 0x67, 0xe5, 0x2f, 0xa3, 0xc5, 0xb2,
|
||||
0xba, 0x8f, 0xd3, 0xc7, 0x4c, 0x18, 0x87, 0xc5,
|
||||
0x93, 0x9b, 0x93, 0x78, 0x9f, 0xca, 0x8c, 0xab,
|
||||
0x73, 0x04, 0x64, 0x01, 0xc9, 0x4f, 0x67, 0xf4,
|
||||
0xb7, 0x6f, 0x0f, 0xd4, 0x0a, 0xe9, 0x77, 0x81,
|
||||
0xa7, 0x18, 0xf8, 0x60, 0xe8, 0x20, 0x45, 0xf2,
|
||||
}),
|
||||
Timestamp: time.Unix(0x5c238b73, 0),
|
||||
Timestamp: time.Unix(0x5c34c293, 0),
|
||||
Bits: 0x207fffff,
|
||||
Nonce: 0xdffffffffffffff9,
|
||||
},
|
||||
@ -363,21 +363,21 @@ var block3A = wire.MsgBlock{
|
||||
Version: 1,
|
||||
ParentHashes: []daghash.Hash{
|
||||
[32]byte{ // Make go vet happy.
|
||||
0x96, 0x2d, 0x1d, 0x2b, 0xc2, 0xf9, 0x30, 0x43,
|
||||
0x88, 0x23, 0xdb, 0x75, 0x73, 0x43, 0xb8, 0xb6,
|
||||
0x76, 0x34, 0x42, 0x55, 0x8f, 0x44, 0x2a, 0x6f,
|
||||
0xb1, 0xac, 0x7e, 0x9b, 0x1f, 0x9f, 0x00, 0x19,
|
||||
0x41, 0x27, 0x85, 0x25, 0x0e, 0x8e, 0xdb, 0xf3,
|
||||
0xb5, 0xdd, 0xfa, 0xb9, 0x75, 0xc0, 0x4f, 0xe8,
|
||||
0x88, 0xff, 0x04, 0x08, 0xe9, 0x0a, 0x93, 0x8f,
|
||||
0x45, 0x04, 0x03, 0x73, 0xc6, 0x24, 0x08, 0x72,
|
||||
},
|
||||
},
|
||||
MerkleRoot: daghash.Hash([32]byte{ // Make go vet happy.
|
||||
0xd3, 0x95, 0x8a, 0x56, 0xfe, 0x89, 0x86, 0x9f,
|
||||
0x47, 0x80, 0x9b, 0xea, 0x51, 0xec, 0x2b, 0x7d,
|
||||
0x76, 0xd5, 0x15, 0xde, 0x98, 0xad, 0x5d, 0x6e,
|
||||
0x79, 0xf5, 0xa4, 0x9b, 0x1b, 0x0c, 0xfa, 0x9b,
|
||||
0x47, 0xb6, 0x23, 0x3a, 0x59, 0xf7, 0x51, 0x40,
|
||||
0x41, 0x2e, 0xf1, 0xa3, 0x35, 0xa6, 0x19, 0xa1,
|
||||
0x89, 0x33, 0x0b, 0x02, 0x29, 0x3f, 0x8f, 0x35,
|
||||
0x92, 0x75, 0x80, 0x61, 0x37, 0x3e, 0x6e, 0x54,
|
||||
}),
|
||||
Timestamp: time.Unix(0x5c238b73, 0),
|
||||
Timestamp: time.Unix(0x5c34c293, 0),
|
||||
Bits: 0x207fffff,
|
||||
Nonce: 0xdffffffffffffff9,
|
||||
Nonce: 0xdffffffffffffffc,
|
||||
},
|
||||
Transactions: []*wire.MsgTx{
|
||||
{
|
||||
@ -418,21 +418,21 @@ var block4 = wire.MsgBlock{
|
||||
Version: 1,
|
||||
ParentHashes: []daghash.Hash{
|
||||
[32]byte{ // Make go vet happy.
|
||||
0x4c, 0xfb, 0xcd, 0x2b, 0x0f, 0x3c, 0xa3, 0x61,
|
||||
0x82, 0xce, 0x34, 0x39, 0x79, 0x0d, 0x22, 0x3b,
|
||||
0x94, 0xdc, 0x7b, 0x66, 0xf8, 0x62, 0xc7, 0xb2,
|
||||
0xd0, 0xfc, 0xb4, 0xf3, 0xc0, 0x7c, 0xa3, 0x63,
|
||||
0xf9, 0x3e, 0x6e, 0x3f, 0x22, 0x4b, 0x36, 0xfc,
|
||||
0x9b, 0xb4, 0xd1, 0x44, 0xbc, 0x62, 0x78, 0xa0,
|
||||
0x2f, 0xef, 0xcc, 0x16, 0xc5, 0x42, 0xbe, 0x59,
|
||||
0x22, 0xfe, 0xec, 0x01, 0x55, 0x03, 0x34, 0x62,
|
||||
},
|
||||
},
|
||||
MerkleRoot: daghash.Hash([32]byte{ // Make go vet happy.
|
||||
0xe0, 0x32, 0x30, 0x4d, 0x53, 0x1d, 0xd4, 0xe0,
|
||||
0xe1, 0xc7, 0x20, 0xf8, 0x28, 0x86, 0x45, 0x9f,
|
||||
0x5d, 0x42, 0x1f, 0x2a, 0xb5, 0xcc, 0x62, 0x7f,
|
||||
0xe7, 0xf2, 0xdd, 0x22, 0x64, 0x7c, 0xc4, 0x66,
|
||||
0x79, 0xa0, 0x0e, 0xd0, 0xaa, 0x17, 0x4e, 0xec,
|
||||
0x73, 0xd3, 0xcf, 0x13, 0x7f, 0x0d, 0x1d, 0xee,
|
||||
0x63, 0x56, 0x3c, 0x2e, 0x17, 0x19, 0x5a, 0x3e,
|
||||
0x8b, 0xd2, 0x99, 0xa4, 0xaf, 0xf9, 0xe6, 0x1e,
|
||||
}),
|
||||
Timestamp: time.Unix(0x5c238b74, 0),
|
||||
Timestamp: time.Unix(0x5c34c294, 0),
|
||||
Bits: 0x207fffff,
|
||||
Nonce: 0xdffffffffffffffb,
|
||||
Nonce: 0xdffffffffffffffa,
|
||||
},
|
||||
Transactions: []*wire.MsgTx{
|
||||
{
|
||||
@ -472,25 +472,25 @@ var block5 = wire.MsgBlock{
|
||||
Version: 1,
|
||||
ParentHashes: []daghash.Hash{
|
||||
[32]byte{ // Make go vet happy.
|
||||
0x03, 0x28, 0xad, 0x11, 0xe6, 0x8f, 0x48, 0x33,
|
||||
0x5c, 0xa8, 0xbb, 0x8c, 0x29, 0xde, 0x43, 0xd5,
|
||||
0x70, 0x8b, 0xbd, 0x1e, 0x61, 0x9d, 0xc8, 0x7d,
|
||||
0xc5, 0x52, 0x86, 0x26, 0x6b, 0x68, 0xec, 0x1f,
|
||||
0xe6, 0x08, 0x3c, 0x96, 0x4f, 0x4c, 0xb5, 0x37,
|
||||
0x2d, 0xd6, 0xe0, 0xe0, 0x85, 0x1a, 0x97, 0x0b,
|
||||
0x22, 0x91, 0x13, 0x80, 0x3b, 0xd1, 0xc8, 0x3d,
|
||||
0x8f, 0x77, 0xd5, 0xd4, 0x39, 0xc4, 0x9a, 0x09,
|
||||
},
|
||||
[32]byte{ // Make go vet happy.
|
||||
0xcf, 0xfd, 0x63, 0x11, 0x72, 0xb7, 0xdc, 0x80,
|
||||
0x59, 0xd0, 0x35, 0x31, 0xed, 0x03, 0x89, 0x3a,
|
||||
0xe9, 0x9b, 0x74, 0xee, 0x86, 0xad, 0x3c, 0x4e,
|
||||
0x0b, 0x08, 0x46, 0xaa, 0x39, 0x30, 0xfa, 0x63,
|
||||
0xfd, 0x28, 0x66, 0x62, 0x56, 0x3e, 0xf0, 0x33,
|
||||
0x85, 0xca, 0xf6, 0x96, 0x0d, 0x3a, 0x73, 0xd1,
|
||||
0x3b, 0xb8, 0xa0, 0xda, 0xae, 0x4d, 0xdc, 0xa6,
|
||||
0x56, 0x82, 0xfd, 0x3b, 0xa0, 0x92, 0x27, 0x38,
|
||||
},
|
||||
},
|
||||
MerkleRoot: daghash.Hash([32]byte{ // Make go vet happy.
|
||||
0x8e, 0xb2, 0xf8, 0x31, 0xec, 0x11, 0xc2, 0x22,
|
||||
0xd1, 0x31, 0x47, 0xf0, 0xbb, 0x48, 0x74, 0xce,
|
||||
0x4a, 0x39, 0x25, 0x99, 0xa7, 0x1c, 0x8c, 0x83,
|
||||
0x98, 0x8d, 0x66, 0xc5, 0x94, 0xa9, 0xf1, 0x50,
|
||||
0x29, 0xc6, 0xbc, 0xd9, 0xac, 0x1d, 0x4a, 0x5e,
|
||||
0xb0, 0x71, 0xfd, 0xac, 0xde, 0x39, 0xc0, 0x9c,
|
||||
0x90, 0xb8, 0x22, 0xde, 0x2d, 0x76, 0x49, 0xab,
|
||||
0x80, 0xdc, 0x77, 0xa8, 0xd7, 0x75, 0x40, 0x18,
|
||||
}),
|
||||
Timestamp: time.Unix(0x5c238b75, 0),
|
||||
Timestamp: time.Unix(0x5c34c295, 0),
|
||||
Bits: 0x207fffff,
|
||||
Nonce: 0xdffffffffffffffa,
|
||||
},
|
||||
|
@ -4,27 +4,57 @@ import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"github.com/daglabs/btcd/dagconfig/daghash"
|
||||
"github.com/daglabs/btcd/util"
|
||||
|
||||
"github.com/daglabs/btcd/database"
|
||||
"github.com/daglabs/btcd/util/subnetworkid"
|
||||
"github.com/daglabs/btcd/wire"
|
||||
)
|
||||
|
||||
// validateAndExtractSubNetworkRegistryTxs filters the given input and extracts a list
|
||||
// of valid sub-network registry transactions.
|
||||
func validateAndExtractSubNetworkRegistryTxs(txs []*TxWithBlockHash) ([]*wire.MsgTx, error) {
|
||||
// registerSubNetworks scans a list of accepted transactions, singles out
|
||||
// sub-network registry transactions, validates them, and registers a new
|
||||
// sub-network based on it.
|
||||
// This function returns an error if one or more transactions are invalid
|
||||
func registerSubNetworks(dbTx database.Tx, txs []*TxWithBlockHash) error {
|
||||
validSubNetworkRegistryTxs := make([]*wire.MsgTx, 0)
|
||||
for _, txData := range txs {
|
||||
tx := txData.Tx.MsgTx()
|
||||
if tx.SubNetworkID == wire.SubNetworkRegistry {
|
||||
err := validateSubNetworkRegistryTransaction(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
validSubNetworkRegistryTxs = append(validSubNetworkRegistryTxs, tx)
|
||||
}
|
||||
|
||||
if subnetworkid.Less(&wire.SubNetworkRegistry, &tx.SubNetworkID) {
|
||||
// Transactions are ordered by sub-network, so we can safely assume
|
||||
// that the rest of the transactions will not be sub-network registry
|
||||
// transactions.
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return validSubNetworkRegistryTxs, nil
|
||||
for _, registryTx := range validSubNetworkRegistryTxs {
|
||||
subNetworkID, err := txToSubNetworkID(registryTx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sNet, err := dbGetSubNetwork(dbTx, subNetworkID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sNet == nil {
|
||||
createdSubNetwork := newSubNetwork(registryTx)
|
||||
err := dbRegisterSubNetwork(dbTx, subNetworkID, createdSubNetwork)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed registering sub-network"+
|
||||
"for tx '%s': %s", registryTx.TxHash(), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateSubNetworkRegistryTransaction makes sure that a given sub-network registry
|
||||
@ -39,66 +69,15 @@ func validateSubNetworkRegistryTransaction(tx *wire.MsgTx) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// registerPendingSubNetworks attempts to register all the pending sub-networks that
|
||||
// had previously been defined between the initial finality point and the new one.
|
||||
// Note: transactions within newFinalityPoint itself are not registered. Instead, they will
|
||||
// be registered when the next finality point is chosen; then it will be the
|
||||
// initialFinalityPoint.
|
||||
func (dag *BlockDAG) registerPendingSubNetworks(dbTx database.Tx, initialFinalityPoint *blockNode, newFinalityPoint *blockNode) error {
|
||||
var stack []*blockNode
|
||||
for currentNode := newFinalityPoint; currentNode != initialFinalityPoint; currentNode = currentNode.selectedParent {
|
||||
stack = append(stack, currentNode)
|
||||
}
|
||||
|
||||
// Register a pending sub-network for all blues. The block itself is not explicitly
|
||||
// registered since it will be one of the blues of the next block.
|
||||
// Note that this means that the very last block in the selected parent chain is not
|
||||
// registered. This is intentional.
|
||||
for i := len(stack) - 1; i >= 0; i-- {
|
||||
currentNode := stack[i]
|
||||
for _, blue := range currentNode.blues {
|
||||
err := dag.registerPendingSubNetworksInBlock(dbTx, blue.hash)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to register pending sub-networks: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
// txToSubNetworkID creates a sub-network ID from a sub-network registry transaction
|
||||
func txToSubNetworkID(tx *wire.MsgTx) (*subnetworkid.SubNetworkID, error) {
|
||||
txHash := tx.TxHash()
|
||||
return subnetworkid.New(util.Hash160(txHash[:]))
|
||||
}
|
||||
|
||||
// registerPendingSubNetworksInBlock attempts to register all the sub-networks
|
||||
// that had been defined in a given block.
|
||||
func (dag *BlockDAG) registerPendingSubNetworksInBlock(dbTx database.Tx, blockHash daghash.Hash) error {
|
||||
pendingSubNetworkTxs, err := dbGetPendingSubNetworkTxs(dbTx, blockHash)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to retrieve pending sub-network txs in block '%s': %s", blockHash, err)
|
||||
}
|
||||
for _, tx := range pendingSubNetworkTxs {
|
||||
if !dbIsRegisteredSubNetworkTx(dbTx, tx.TxHash()) {
|
||||
createdSubNetwork := newSubNetwork(tx)
|
||||
err := dbRegisterSubNetwork(dbTx, dag.lastSubNetworkID, tx.TxHash(), createdSubNetwork)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed registering sub-network"+
|
||||
"for tx '%s' in block '%s': %s", tx.TxHash(), blockHash, err)
|
||||
}
|
||||
|
||||
dag.lastSubNetworkID++
|
||||
}
|
||||
}
|
||||
|
||||
err = dbRemovePendingSubNetworkTxs(dbTx, blockHash)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to remove block '%s'"+
|
||||
"from pending sub-networks: %s", blockHash, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// subNetwork returns a registered-and-finalized sub-network. If the sub-network
|
||||
// does not exist this method returns an error.
|
||||
func (dag *BlockDAG) subNetwork(subNetworkID uint64) (*subNetwork, error) {
|
||||
// subNetwork returns a registered sub-network. If the sub-network does not exist
|
||||
// this method returns an error.
|
||||
func (dag *BlockDAG) subNetwork(subNetworkID *subnetworkid.SubNetworkID) (*subNetwork, error) {
|
||||
var sNet *subNetwork
|
||||
var err error
|
||||
dbErr := dag.db.View(func(dbTx database.Tx) error {
|
||||
@ -115,217 +94,70 @@ func (dag *BlockDAG) subNetwork(subNetworkID uint64) (*subNetwork, error) {
|
||||
return sNet, nil
|
||||
}
|
||||
|
||||
// GasLimit returns the gas limit of a registered-and-finalized sub-network. If
|
||||
// the sub-network does not exist this method returns an error.
|
||||
func (dag *BlockDAG) GasLimit(subNetworkID uint64) (uint64, error) {
|
||||
// GasLimit returns the gas limit of a registered sub-network. If the sub-network does not
|
||||
// exist this method returns an error.
|
||||
func (dag *BlockDAG) GasLimit(subNetworkID *subnetworkid.SubNetworkID) (uint64, error) {
|
||||
sNet, err := dag.subNetwork(subNetworkID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if sNet == nil {
|
||||
return 0, fmt.Errorf("sub-network '%s' not found", subNetworkID)
|
||||
}
|
||||
|
||||
return sNet.gasLimit, nil
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// The sub-network registry consists of three buckets:
|
||||
// a. The pending sub-network bucket
|
||||
// b. The registered transaction bucket
|
||||
// c. The sub-network bucket
|
||||
//
|
||||
// All newly-discovered sub-network registry transactions are stored in the
|
||||
// pending sub-network bucket. These transactions are withheld until the
|
||||
// blocks that contain them become final.
|
||||
//
|
||||
// Once the block of a sub-network registry transaction becomes final, all the
|
||||
// transactions within that block are retrieved and checked for validity.
|
||||
// Valid transactions are then:
|
||||
// 1. Assigned a sub-network ID
|
||||
// 2. Added to the registered transaction bucket
|
||||
// 3. Added to the sub-network bucket
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// dbPutPendingSubNetworkTxs stores mappings from a block (via its hash) to an
|
||||
// array of sub-network transactions.
|
||||
func dbPutPendingSubNetworkTxs(dbTx database.Tx, blockHash *daghash.Hash, subNetworkRegistryTxs []*wire.MsgTx) error {
|
||||
// Empty blocks are not written
|
||||
if len(subNetworkRegistryTxs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
serializedTxs, err := serializeSubNetworkRegistryTxs(subNetworkRegistryTxs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to serialize pending sub-network txs in block '%s': %s", blockHash, err)
|
||||
}
|
||||
|
||||
// Store the serialized transactions
|
||||
bucket := dbTx.Metadata().Bucket(pendingSubNetworksBucketName)
|
||||
err = bucket.Put(blockHash[:], serializedTxs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write pending sub-network txs in block '%s': %s", blockHash, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// dbGetPendingSubNetworkTxs retrieves an array of sub-network transactions,
|
||||
// associated with a block's hash, that was previously stored with
|
||||
// dbPutPendingSubNetworkTxs.
|
||||
// Returns an empty slice if the hash was not previously stored.
|
||||
func dbGetPendingSubNetworkTxs(dbTx database.Tx, blockHash daghash.Hash) ([]*wire.MsgTx, error) {
|
||||
bucket := dbTx.Metadata().Bucket(pendingSubNetworksBucketName)
|
||||
serializedTxsBytes := bucket.Get(blockHash[:])
|
||||
if serializedTxsBytes == nil {
|
||||
return []*wire.MsgTx{}, nil
|
||||
}
|
||||
|
||||
txs, err := deserializeSubNetworkRegistryTxs(serializedTxsBytes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to deserialize pending sub-network txs for block '%s': %s", blockHash, err)
|
||||
}
|
||||
|
||||
return txs, nil
|
||||
}
|
||||
|
||||
// serializeSubNetworkRegistryTxs serializes a slice of MsgTxs by serializing each transaction
|
||||
// individually and appending it to one long byte slice.
|
||||
func serializeSubNetworkRegistryTxs(subNetworkRegistryTxs []*wire.MsgTx) ([]byte, error) {
|
||||
// Calculate the length in bytes of the serialized transactions
|
||||
serializedTxsLength := uint64(0)
|
||||
for _, tx := range subNetworkRegistryTxs {
|
||||
serializedTxsLength += uint64(tx.SerializeSize())
|
||||
}
|
||||
serializedTxs := bytes.NewBuffer(make([]byte, 0, serializedTxsLength))
|
||||
|
||||
// Write each transaction in the order it appears in
|
||||
for _, tx := range subNetworkRegistryTxs {
|
||||
err := tx.Serialize(serializedTxs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to serialize tx '%s': %s", tx.TxHash(), err)
|
||||
}
|
||||
}
|
||||
|
||||
return serializedTxs.Bytes(), nil
|
||||
}
|
||||
|
||||
// deserializeSubNetworkRegistryTxs deserializes a byte slice into a slice of MsgTxs.
|
||||
func deserializeSubNetworkRegistryTxs(serializedTxsBytes []byte) ([]*wire.MsgTx, error) {
|
||||
serializedTxs := bytes.NewBuffer(serializedTxsBytes)
|
||||
|
||||
// Read each transaction and store it in txs until the end of the buffer
|
||||
txs := make([]*wire.MsgTx, 0)
|
||||
for serializedTxs.Len() > 0 {
|
||||
var tx wire.MsgTx
|
||||
err := tx.Deserialize(serializedTxs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to deserialize pending sub-network txs: %s", err)
|
||||
}
|
||||
|
||||
txs = append(txs, &tx)
|
||||
}
|
||||
|
||||
return txs, nil
|
||||
}
|
||||
|
||||
// dbRemovePendingSubNetworkTxs deletes an array of sub-network transactions,
|
||||
// associated with a block's hash, that was previously stored with
|
||||
// dbPutPendingSubNetworkTxs.
|
||||
// This function does not return an error if the hash was not previously stored.
|
||||
func dbRemovePendingSubNetworkTxs(dbTx database.Tx, blockHash daghash.Hash) error {
|
||||
bucket := dbTx.Metadata().Bucket(pendingSubNetworksBucketName)
|
||||
|
||||
err := bucket.Delete(blockHash[:])
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to remove pending sub-network txs in block '%s': %s", blockHash, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// dbIsRegisteredSubNetworkTx checks whether a sub-network registry transaction
|
||||
// had successfully registered a sub-network.
|
||||
func dbIsRegisteredSubNetworkTx(dbTx database.Tx, txHash daghash.Hash) bool {
|
||||
bucket := dbTx.Metadata().Bucket(registeredSubNetworkTxsBucketName)
|
||||
subNetworkIDBytes := bucket.Get(txHash[:])
|
||||
|
||||
return subNetworkIDBytes != nil
|
||||
}
|
||||
|
||||
// dbRegisterSubNetwork stores mappings:
|
||||
// a. from the ID of the sub-network to the sub-network data.
|
||||
// b. from the hash of a sub-network registry transaction to the sub-network ID.
|
||||
func dbRegisterSubNetwork(dbTx database.Tx, subNetworkID uint64, txHash daghash.Hash, network *subNetwork) error {
|
||||
// Serialize the sub-network ID
|
||||
subNetworkIDBytes := make([]byte, 8)
|
||||
byteOrder.PutUint64(subNetworkIDBytes, subNetworkID)
|
||||
|
||||
// dbRegisterSubNetwork stores mappings from ID of the sub-network to the sub-network data.
|
||||
func dbRegisterSubNetwork(dbTx database.Tx, subNetworkID *subnetworkid.SubNetworkID, network *subNetwork) error {
|
||||
// Serialize the sub-network
|
||||
serializedSubNetwork, err := serializeSubNetwork(network)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to serialize sub-netowrk of tx '%s': %s", network.txHash, err)
|
||||
return fmt.Errorf("failed to serialize sub-netowrk '%s': %s", subNetworkID, err)
|
||||
}
|
||||
|
||||
// Store the sub-network
|
||||
subNetworksBucket := dbTx.Metadata().Bucket(subNetworksBucketName)
|
||||
err = subNetworksBucket.Put(subNetworkIDBytes, serializedSubNetwork)
|
||||
err = subNetworksBucket.Put(subNetworkID[:], serializedSubNetwork)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to write sub-netowrk of tx '%s': %s", network.txHash, err)
|
||||
}
|
||||
|
||||
// Store the mapping between txHash and subNetworkID
|
||||
registeredSubNetworkTxs := dbTx.Metadata().Bucket(registeredSubNetworkTxsBucketName)
|
||||
err = registeredSubNetworkTxs.Put(txHash[:], subNetworkIDBytes)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to put registered sub-networkTx '%s': %s", txHash, err)
|
||||
return fmt.Errorf("failed to write sub-netowrk '%s': %s", subNetworkID, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func dbGetSubNetwork(dbTx database.Tx, subNetworkID uint64) (*subNetwork, error) {
|
||||
// Serialize the sub-network ID
|
||||
subNetworkIDBytes := make([]byte, 8)
|
||||
byteOrder.PutUint64(subNetworkIDBytes, subNetworkID)
|
||||
|
||||
// Get the sub-network
|
||||
// dbGetSubNetwork returns the sub-network associated with subNetworkID or nil if the sub-network was not found.
|
||||
func dbGetSubNetwork(dbTx database.Tx, subNetworkID *subnetworkid.SubNetworkID) (*subNetwork, error) {
|
||||
bucket := dbTx.Metadata().Bucket(subNetworksBucketName)
|
||||
serializedSubNetwork := bucket.Get(subNetworkIDBytes)
|
||||
serializedSubNetwork := bucket.Get(subNetworkID[:])
|
||||
if serializedSubNetwork == nil {
|
||||
return nil, fmt.Errorf("sub-network '%d' not found", subNetworkID)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return deserializeSubNetwork(serializedSubNetwork)
|
||||
}
|
||||
|
||||
type subNetwork struct {
|
||||
txHash daghash.Hash
|
||||
gasLimit uint64
|
||||
}
|
||||
|
||||
func newSubNetwork(tx *wire.MsgTx) *subNetwork {
|
||||
txHash := tx.TxHash()
|
||||
gasLimit := binary.LittleEndian.Uint64(tx.Payload[:8])
|
||||
|
||||
return &subNetwork{
|
||||
txHash: txHash,
|
||||
gasLimit: gasLimit,
|
||||
}
|
||||
}
|
||||
|
||||
// serializeSubNetwork serializes a subNetwork into the following binary format:
|
||||
// | txHash (32 bytes) | gasLimit (8 bytes) |
|
||||
// | gasLimit (8 bytes) |
|
||||
func serializeSubNetwork(sNet *subNetwork) ([]byte, error) {
|
||||
serializedSNet := bytes.NewBuffer(make([]byte, 0, 40))
|
||||
|
||||
// Write the tx hash
|
||||
err := binary.Write(serializedSNet, byteOrder, sNet.txHash)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to serialize sub-network for tx '%s': %s", sNet.txHash, err)
|
||||
}
|
||||
serializedSNet := bytes.NewBuffer(make([]byte, 0, 8))
|
||||
|
||||
// Write the gas limit
|
||||
err = binary.Write(serializedSNet, byteOrder, sNet.gasLimit)
|
||||
err := binary.Write(serializedSNet, byteOrder, sNet.gasLimit)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to serialize sub-network for tx '%s': %s", sNet.txHash, err)
|
||||
return nil, fmt.Errorf("failed to serialize sub-network: %s", err)
|
||||
}
|
||||
|
||||
return serializedSNet.Bytes(), nil
|
||||
@ -336,22 +168,14 @@ func serializeSubNetwork(sNet *subNetwork) ([]byte, error) {
|
||||
func deserializeSubNetwork(serializedSNetBytes []byte) (*subNetwork, error) {
|
||||
serializedSNet := bytes.NewBuffer(serializedSNetBytes)
|
||||
|
||||
// Read the tx hash
|
||||
var txHash daghash.Hash
|
||||
err := binary.Read(serializedSNet, byteOrder, &txHash)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to deserialize sub-network: %s", err)
|
||||
}
|
||||
|
||||
// Read the gas limit
|
||||
var gasLimit uint64
|
||||
err = binary.Read(serializedSNet, byteOrder, &gasLimit)
|
||||
err := binary.Read(serializedSNet, byteOrder, &gasLimit)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to deserialize sub-network: %s", err)
|
||||
}
|
||||
|
||||
return &subNetwork{
|
||||
txHash: txHash,
|
||||
gasLimit: gasLimit,
|
||||
}, nil
|
||||
}
|
||||
|
@ -1,23 +1,17 @@
|
||||
package blockdag
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"math"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/daglabs/btcd/dagconfig"
|
||||
"github.com/daglabs/btcd/wire"
|
||||
)
|
||||
|
||||
// TestSubNetworkRegistry tests the full sub-network registry flow. In this test:
|
||||
// 1. We create a sub-network registry transaction and add its block to the DAG
|
||||
// 2. Add 2*finalityInterval so that the sub-network registry transaction becomes final
|
||||
// 3. Attempt to retrieve the gas limit of the now-registered sub-network
|
||||
// TestSubNetworkRegistry tests the full sub-network registry flow
|
||||
func TestSubNetworkRegistry(t *testing.T) {
|
||||
params := dagconfig.SimNetParams
|
||||
params.K = 1
|
||||
dag, teardownFunc, err := DAGSetup("TestFinality", Config{
|
||||
dag, teardownFunc, err := DAGSetup("TestSubNetworkRegistry", Config{
|
||||
DAGParams: ¶ms,
|
||||
})
|
||||
if err != nil {
|
||||
@ -25,103 +19,22 @@ func TestSubNetworkRegistry(t *testing.T) {
|
||||
}
|
||||
defer teardownFunc()
|
||||
|
||||
_, err = RegisterSubnetworkForTest(dag, 12345)
|
||||
|
||||
gasLimit := uint64(12345)
|
||||
subNetworkID, err := RegisterSubNetworkForTest(dag, gasLimit)
|
||||
if err != nil {
|
||||
t.Fatalf("could not register network: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSerializeSubNetworkRegistryTxs(t *testing.T) {
|
||||
payload1 := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(payload1, uint64(100))
|
||||
tx1 := wire.MsgTx{
|
||||
Version: 1,
|
||||
SubNetworkID: wire.SubNetworkRegistry,
|
||||
Payload: payload1,
|
||||
TxIn: []*wire.TxIn{
|
||||
{
|
||||
PreviousOutPoint: wire.OutPoint{
|
||||
Hash: *newHashFromStr("0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9"),
|
||||
Index: 0,
|
||||
},
|
||||
SignatureScript: hexToBytes("47304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901"),
|
||||
Sequence: math.MaxUint64,
|
||||
},
|
||||
},
|
||||
TxOut: []*wire.TxOut{{
|
||||
Value: 1000000000,
|
||||
PkScript: hexToBytes("4104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac"),
|
||||
}, {
|
||||
Value: 4000000000,
|
||||
PkScript: hexToBytes("410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac"),
|
||||
}},
|
||||
limit, err := dag.GasLimit(subNetworkID)
|
||||
if err != nil {
|
||||
t.Fatalf("could not retrieve gas limit: %s", err)
|
||||
}
|
||||
|
||||
payload2 := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(payload2, uint64(200))
|
||||
tx2 := wire.MsgTx{
|
||||
Version: 1,
|
||||
SubNetworkID: wire.SubNetworkRegistry,
|
||||
Payload: payload2,
|
||||
TxIn: []*wire.TxIn{{
|
||||
PreviousOutPoint: wire.OutPoint{
|
||||
Hash: *newHashFromStr("0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9"),
|
||||
Index: 0,
|
||||
},
|
||||
SignatureScript: hexToBytes("47304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901"),
|
||||
Sequence: math.MaxUint64,
|
||||
}},
|
||||
TxOut: []*wire.TxOut{{
|
||||
Value: 5000000,
|
||||
PkScript: hexToBytes("76a914f419b8db4ba65f3b6fcc233acb762ca6f51c23d488ac"),
|
||||
}, {
|
||||
Value: 34400000000,
|
||||
PkScript: hexToBytes("76a914cadf4fc336ab3c6a4610b75f31ba0676b7f663d288ac"),
|
||||
}},
|
||||
LockTime: 0,
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
txs []*wire.MsgTx
|
||||
}{
|
||||
{
|
||||
name: "empty slice",
|
||||
txs: []*wire.MsgTx{},
|
||||
},
|
||||
{
|
||||
name: "one transaction",
|
||||
txs: []*wire.MsgTx{&tx1},
|
||||
},
|
||||
{
|
||||
name: "two transactions",
|
||||
txs: []*wire.MsgTx{&tx2, &tx1},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
serializedTxs, err := serializeSubNetworkRegistryTxs(test.txs)
|
||||
if err != nil {
|
||||
t.Errorf("serialization in test '%s' unexpectedly failed: %s", test.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
deserializedTxs, err := deserializeSubNetworkRegistryTxs(serializedTxs)
|
||||
if err != nil {
|
||||
t.Errorf("deserialization in test '%s' unexpectedly failed: %s", test.name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(test.txs, deserializedTxs) {
|
||||
t.Errorf("original txs and deserialized txs are not equal in test '%s'", test.name)
|
||||
}
|
||||
if limit != gasLimit {
|
||||
t.Fatalf("unexpected gas limit. want: %d, got: %d", gasLimit, limit)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSerializeSubNetwork(t *testing.T) {
|
||||
sNet := &subNetwork{
|
||||
txHash: *newHashFromStr("0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9"),
|
||||
gasLimit: 1000,
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package blockdag
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"github.com/daglabs/btcd/util/subnetworkid"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
@ -143,9 +144,9 @@ func createCoinbaseTxForTest(blockHeight int32, numOutputs uint32, extraNonce in
|
||||
return tx, nil
|
||||
}
|
||||
|
||||
// RegisterSubnetworkForTest is used to register network on DAG with specified GAS limit.
|
||||
func RegisterSubnetworkForTest(dag *BlockDAG, gasLimit uint64) (subNetworkID uint64, err error) {
|
||||
blockTime := time.Unix(dag.genesis.timestamp, 0)
|
||||
// RegisterSubNetworkForTest is used to register network on DAG with specified gas limit
|
||||
func RegisterSubNetworkForTest(dag *BlockDAG, gasLimit uint64) (*subnetworkid.SubNetworkID, error) {
|
||||
blockTime := time.Unix(dag.selectedTip().timestamp, 0)
|
||||
extraNonce := int64(0)
|
||||
|
||||
buildNextBlock := func(parents blockSet, txs []*wire.MsgTx) (*util.Block, error) {
|
||||
@ -180,7 +181,7 @@ func RegisterSubnetworkForTest(dag *BlockDAG, gasLimit uint64) (subNetworkID uin
|
||||
dag.dagLock.Lock()
|
||||
defer dag.dagLock.Unlock()
|
||||
|
||||
err = dag.maybeAcceptBlock(block, BFNone)
|
||||
err := dag.maybeAcceptBlock(block, BFNone)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -188,7 +189,7 @@ func RegisterSubnetworkForTest(dag *BlockDAG, gasLimit uint64) (subNetworkID uin
|
||||
return dag.index.LookupNode(block.Hash()), nil
|
||||
}
|
||||
|
||||
currentNode := dag.genesis
|
||||
currentNode := dag.selectedTip()
|
||||
|
||||
// Create a block with a valid sub-network registry transaction
|
||||
registryTx := wire.NewMsgTx(wire.TxVersion)
|
||||
@ -199,34 +200,17 @@ func RegisterSubnetworkForTest(dag *BlockDAG, gasLimit uint64) (subNetworkID uin
|
||||
// Add it to the DAG
|
||||
registryBlock, err := buildNextBlock(setFromSlice(currentNode), []*wire.MsgTx{registryTx})
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("could not build registry block: %s", err)
|
||||
return nil, fmt.Errorf("could not build registry block: %s", err)
|
||||
}
|
||||
currentNode, err = addBlockToDAG(registryBlock)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("could not add registry block to DAG: %s", err)
|
||||
return nil, fmt.Errorf("could not add registry block to DAG: %s", err)
|
||||
}
|
||||
|
||||
// Add 2*finalityInterval to ensure the registry transaction is finalized
|
||||
for currentNode.blueScore < 2*finalityInterval {
|
||||
nextBlock, err := buildNextBlock(setFromSlice(currentNode), []*wire.MsgTx{})
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("could not create block: %s", err)
|
||||
}
|
||||
currentNode, err = addBlockToDAG(nextBlock)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("could not add block to DAG: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure that the sub-network had been successfully registered by trying
|
||||
// to retrieve its gas limit.
|
||||
mostRecentlyRegisteredSubNetworkID := dag.lastSubNetworkID - 1
|
||||
limit, err := dag.GasLimit(mostRecentlyRegisteredSubNetworkID)
|
||||
// Build a sub-network ID from the registry transaction
|
||||
subNetworkID, err := txToSubNetworkID(registryTx)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("could not retrieve gas limit: %s", err)
|
||||
return nil, fmt.Errorf("could not build sub-network ID: %s", err)
|
||||
}
|
||||
if limit != gasLimit {
|
||||
return 0, fmt.Errorf("unexpected gas limit. want: %d, got: %d", gasLimit, limit)
|
||||
}
|
||||
return mostRecentlyRegisteredSubNetworkID, nil
|
||||
return subNetworkID, nil
|
||||
}
|
||||
|
BIN
blockdag/testdata/blk_0_to_4.dat
vendored
BIN
blockdag/testdata/blk_0_to_4.dat
vendored
Binary file not shown.
BIN
blockdag/testdata/blk_3A.dat
vendored
BIN
blockdag/testdata/blk_3A.dat
vendored
Binary file not shown.
BIN
blockdag/testdata/blk_3B.dat
vendored
BIN
blockdag/testdata/blk_3B.dat
vendored
Binary file not shown.
BIN
blockdag/testdata/blk_3C.dat
vendored
BIN
blockdag/testdata/blk_3C.dat
vendored
Binary file not shown.
BIN
blockdag/testdata/blk_3D.dat
vendored
BIN
blockdag/testdata/blk_3D.dat
vendored
Binary file not shown.
@ -16,6 +16,7 @@ import (
|
||||
"github.com/daglabs/btcd/dagconfig/daghash"
|
||||
"github.com/daglabs/btcd/txscript"
|
||||
"github.com/daglabs/btcd/util"
|
||||
"github.com/daglabs/btcd/util/subnetworkid"
|
||||
"github.com/daglabs/btcd/wire"
|
||||
)
|
||||
|
||||
@ -496,7 +497,7 @@ func checkBlockSanity(block *util.Block, powLimit *big.Int, timeSource MedianTim
|
||||
"index %d", i+1)
|
||||
return ruleError(ErrMultipleCoinbases, str)
|
||||
}
|
||||
if tx.MsgTx().SubNetworkID < transactions[i].MsgTx().SubNetworkID {
|
||||
if subnetworkid.Less(&tx.MsgTx().SubNetworkID, &transactions[i].MsgTx().SubNetworkID) {
|
||||
return ruleError(ErrTransactionsNotSorted, "transactions must be sorted by subnetwork")
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"github.com/daglabs/btcd/dagconfig"
|
||||
"github.com/daglabs/btcd/dagconfig/daghash"
|
||||
"github.com/daglabs/btcd/util"
|
||||
"github.com/daglabs/btcd/util/subnetworkid"
|
||||
"github.com/daglabs/btcd/wire"
|
||||
)
|
||||
|
||||
@ -640,14 +641,14 @@ var Block100000 = wire.MsgBlock{
|
||||
},
|
||||
},
|
||||
MerkleRoot: daghash.Hash([32]byte{ // Make go vet happy.
|
||||
0x0b, 0x79, 0xf5, 0x29, 0x6d, 0x1c, 0xaa, 0x90,
|
||||
0x2f, 0x01, 0xd4, 0x83, 0x9b, 0x2a, 0x04, 0x5e,
|
||||
0xa0, 0x69, 0x2d, 0x16, 0xb5, 0xd7, 0xe4, 0xf3,
|
||||
0xcd, 0xc7, 0xc9, 0xaf, 0xfb, 0xd2, 0x1b, 0x85,
|
||||
0xe8, 0x09, 0xa1, 0x6c, 0xf2, 0xfb, 0xb1, 0x2d,
|
||||
0xff, 0xff, 0x7d, 0x0f, 0x5b, 0xdc, 0xaa, 0xfd,
|
||||
0xf1, 0xe4, 0x92, 0x23, 0x1b, 0x8c, 0xbf, 0x6a,
|
||||
0x28, 0x52, 0x10, 0x9f, 0x93, 0x96, 0x1f, 0x25,
|
||||
}),
|
||||
Timestamp: time.Unix(0x5c22330f, 0),
|
||||
Bits: 0x207fffff,
|
||||
Nonce: 0xdffffffffffffffc,
|
||||
Nonce: 1,
|
||||
},
|
||||
Transactions: []*wire.MsgTx{
|
||||
{
|
||||
@ -1014,7 +1015,7 @@ var BlockWithWrongTxOrder = wire.MsgBlock{
|
||||
},
|
||||
},
|
||||
LockTime: 0,
|
||||
SubNetworkID: wire.SubNetworkDAGCoin + 10,
|
||||
SubNetworkID: subnetworkid.SubNetworkID{11},
|
||||
},
|
||||
{
|
||||
Version: 1,
|
||||
|
@ -28,6 +28,7 @@ import (
|
||||
"github.com/daglabs/btcd/mempool"
|
||||
"github.com/daglabs/btcd/util"
|
||||
"github.com/daglabs/btcd/util/network"
|
||||
"github.com/daglabs/btcd/util/subnetworkid"
|
||||
"github.com/daglabs/btcd/version"
|
||||
"github.com/daglabs/btcd/wire"
|
||||
"github.com/jessevdk/go-flags"
|
||||
@ -165,7 +166,7 @@ type configFlags struct {
|
||||
DropAddrIndex bool `long:"dropaddrindex" description:"Deletes the address-based transaction index from the database on start up and then exits."`
|
||||
RelayNonStd bool `long:"relaynonstd" description:"Relay non-standard transactions regardless of the default settings for the active network."`
|
||||
RejectNonStd bool `long:"rejectnonstd" description:"Reject non-standard transactions regardless of the default settings for the active network."`
|
||||
SubNetwork uint64 `long:"subnetwork" description:"If subnetwork > 0, than node will request and process only payloads from specified subnetwork. And if subnetwork is 0, than payloads of all subnetworks are processed. Subnetworks 3 through 255 are reserved for future use and are currently not allowed."`
|
||||
SubNetwork string `string:"subnetwork" description:"If subnetwork != 0, than node will request and process only payloads from specified subnetwork. And if subnetwork is 0, than payloads of all subnetworks are processed. Subnetworks 3 through 255 are reserved for future use and are currently not allowed."`
|
||||
}
|
||||
|
||||
// Config defines the configuration options for btcd.
|
||||
@ -180,6 +181,7 @@ type Config struct {
|
||||
MiningAddrs []util.Address
|
||||
MinRelayTxFee util.Amount
|
||||
Whitelists []*net.IPNet
|
||||
SubNetwork *subnetworkid.SubNetworkID
|
||||
}
|
||||
|
||||
// serviceOptions defines the configuration options for the daemon as a service on
|
||||
@ -751,16 +753,15 @@ func loadConfig() (*Config, []string, error) {
|
||||
cfg.MiningAddrs = append(cfg.MiningAddrs, addr)
|
||||
}
|
||||
|
||||
if cfg.SubNetwork >= wire.SubNetworkReservedFirst && cfg.SubNetwork < wire.SubNetworkUnreservedFirst {
|
||||
str := "%s: subnetworkID %d is reserved for future use, and nodes can not run in it "
|
||||
err := fmt.Errorf(str, funcName, cfg.SubNetwork)
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
fmt.Fprintln(os.Stderr, usageMessage)
|
||||
return nil, nil, err
|
||||
if cfg.configFlags.SubNetwork != "" {
|
||||
cfg.SubNetwork, err = subnetworkid.NewFromStr(cfg.configFlags.SubNetwork)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Check that 'generate' and 'subnetwork' flags do not conflict
|
||||
if cfg.Generate && cfg.SubNetwork != wire.SubNetworkSupportsAll {
|
||||
if cfg.Generate && *cfg.SubNetwork != wire.SubNetworkSupportsAll {
|
||||
str := "%s: both generate flag and subnetwork filtering are set "
|
||||
err := fmt.Errorf(str, funcName)
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/daglabs/btcd/util/subnetworkid"
|
||||
"github.com/daglabs/btcd/wire"
|
||||
)
|
||||
|
||||
@ -75,15 +76,8 @@ func TestCreateDefaultConfigFile(t *testing.T) {
|
||||
|
||||
// TestConstants makes sure that all constants hard-coded into the help text were not modified.
|
||||
func TestConstants(t *testing.T) {
|
||||
if wire.SubNetworkSupportsAll != 0 {
|
||||
zero := subnetworkid.SubNetworkID{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
if wire.SubNetworkSupportsAll != zero {
|
||||
t.Errorf("wire.SubNetworkSupportsAll value was changed from 0, therefore you probably need to update the help text for SubNetwork")
|
||||
}
|
||||
|
||||
if wire.SubNetworkReservedFirst != 3 {
|
||||
t.Errorf("wire.SubNetworkReservedFirst value was changed from 0, therefore you probably need to update the help text for SubNetwork")
|
||||
}
|
||||
|
||||
if wire.SubNetworkUnreservedFirst != 256 {
|
||||
t.Errorf("wire.SubNetworkUnreservedFirst value was changed from 0, therefore you probably need to update the help text for SubNetwork")
|
||||
}
|
||||
}
|
||||
|
@ -60,19 +60,19 @@ var genesisCoinbaseTx = wire.MsgTx{
|
||||
// genesisHash is the hash of the first block in the block chain for the main
|
||||
// network (genesis block).
|
||||
var genesisHash = daghash.Hash([daghash.HashSize]byte{ // Make go vet happy.
|
||||
0x34, 0x16, 0x17, 0x85, 0x5d, 0xf7, 0x79, 0xde,
|
||||
0xdc, 0x37, 0xf0, 0x57, 0x93, 0x9d, 0x6f, 0x22,
|
||||
0xe5, 0xff, 0xa0, 0x3e, 0xc7, 0x3e, 0x50, 0xf5,
|
||||
0xa1, 0x2a, 0x0a, 0x2e, 0x48, 0x05, 0xc2, 0x47,
|
||||
0xca, 0xd9, 0x5f, 0x65, 0x44, 0xd4, 0x2f, 0x08,
|
||||
0x23, 0x22, 0x93, 0x4c, 0x07, 0xd9, 0xa4, 0xc0,
|
||||
0x1a, 0x51, 0x77, 0xf6, 0x13, 0x7c, 0x06, 0x8b,
|
||||
0xd2, 0x6d, 0xe1, 0x38, 0xea, 0x12, 0xcd, 0x4a,
|
||||
})
|
||||
|
||||
// genesisMerkleRoot is the hash of the first transaction in the genesis block
|
||||
// for the main network.
|
||||
var genesisMerkleRoot = daghash.Hash([daghash.HashSize]byte{ // Make go vet happy.
|
||||
0x79, 0x6e, 0xd7, 0x12, 0x58, 0xea, 0x3f, 0x88,
|
||||
0xa1, 0xfa, 0x7a, 0x67, 0x2b, 0x68, 0x76, 0x6b,
|
||||
0x39, 0x6b, 0x7d, 0x15, 0x6b, 0x1a, 0xb1, 0x96,
|
||||
0xe2, 0x17, 0x2c, 0x4a, 0x6a, 0xad, 0x72, 0x96,
|
||||
0x5a, 0x7c, 0x26, 0x54, 0x0d, 0x46, 0x6b, 0x5f,
|
||||
0x4a, 0x2c, 0x29, 0xff, 0x2f, 0xa5, 0xa0, 0xad,
|
||||
0x9c, 0xd2, 0x4f, 0x6e, 0xa9, 0x16, 0xfa, 0xb5,
|
||||
0x52, 0x5e, 0x40, 0xa2, 0x69, 0xb6, 0x8d, 0x5c,
|
||||
})
|
||||
|
||||
// genesisBlock defines the genesis block of the block chain which serves as the
|
||||
@ -82,9 +82,9 @@ var genesisBlock = wire.MsgBlock{
|
||||
Version: 1,
|
||||
ParentHashes: []daghash.Hash{},
|
||||
MerkleRoot: genesisMerkleRoot,
|
||||
Timestamp: time.Unix(0x5c238413, 0),
|
||||
Timestamp: time.Unix(0x5c34b3ba, 0),
|
||||
Bits: 0x207fffff,
|
||||
Nonce: 0x00000001,
|
||||
Nonce: 0xdffffffffffffff9,
|
||||
},
|
||||
Transactions: []*wire.MsgTx{&genesisCoinbaseTx},
|
||||
}
|
||||
@ -92,10 +92,10 @@ var genesisBlock = wire.MsgBlock{
|
||||
// regTestGenesisHash is the hash of the first block in the block chain for the
|
||||
// regression test network (genesis block).
|
||||
var regTestGenesisHash = daghash.Hash([daghash.HashSize]byte{ // Make go vet happy.
|
||||
0x34, 0x16, 0x17, 0x85, 0x5d, 0xf7, 0x79, 0xde,
|
||||
0xdc, 0x37, 0xf0, 0x57, 0x93, 0x9d, 0x6f, 0x22,
|
||||
0xe5, 0xff, 0xa0, 0x3e, 0xc7, 0x3e, 0x50, 0xf5,
|
||||
0xa1, 0x2a, 0x0a, 0x2e, 0x48, 0x05, 0xc2, 0x47,
|
||||
0xca, 0xd9, 0x5f, 0x65, 0x44, 0xd4, 0x2f, 0x08,
|
||||
0x23, 0x22, 0x93, 0x4c, 0x07, 0xd9, 0xa4, 0xc0,
|
||||
0x1a, 0x51, 0x77, 0xf6, 0x13, 0x7c, 0x06, 0x8b,
|
||||
0xd2, 0x6d, 0xe1, 0x38, 0xea, 0x12, 0xcd, 0x4a,
|
||||
})
|
||||
|
||||
// regTestGenesisMerkleRoot is the hash of the first transaction in the genesis
|
||||
@ -110,9 +110,9 @@ var regTestGenesisBlock = wire.MsgBlock{
|
||||
Version: 1,
|
||||
ParentHashes: []daghash.Hash{},
|
||||
MerkleRoot: genesisMerkleRoot,
|
||||
Timestamp: time.Unix(0x5c238413, 0),
|
||||
Timestamp: time.Unix(0x5c34b3ba, 0),
|
||||
Bits: 0x207fffff,
|
||||
Nonce: 0x00000001,
|
||||
Nonce: 0xdffffffffffffff9,
|
||||
},
|
||||
Transactions: []*wire.MsgTx{&genesisCoinbaseTx},
|
||||
}
|
||||
@ -120,10 +120,10 @@ var regTestGenesisBlock = wire.MsgBlock{
|
||||
// testNet3GenesisHash is the hash of the first block in the block chain for the
|
||||
// test network (version 3).
|
||||
var testNet3GenesisHash = daghash.Hash([daghash.HashSize]byte{ // Make go vet happy.
|
||||
0x34, 0x16, 0x17, 0x85, 0x5d, 0xf7, 0x79, 0xde,
|
||||
0xdc, 0x37, 0xf0, 0x57, 0x93, 0x9d, 0x6f, 0x22,
|
||||
0xe5, 0xff, 0xa0, 0x3e, 0xc7, 0x3e, 0x50, 0xf5,
|
||||
0xa1, 0x2a, 0x0a, 0x2e, 0x48, 0x05, 0xc2, 0x47,
|
||||
0xca, 0xd9, 0x5f, 0x65, 0x44, 0xd4, 0x2f, 0x08,
|
||||
0x23, 0x22, 0x93, 0x4c, 0x07, 0xd9, 0xa4, 0xc0,
|
||||
0x1a, 0x51, 0x77, 0xf6, 0x13, 0x7c, 0x06, 0x8b,
|
||||
0xd2, 0x6d, 0xe1, 0x38, 0xea, 0x12, 0xcd, 0x4a,
|
||||
})
|
||||
|
||||
// testNet3GenesisMerkleRoot is the hash of the first transaction in the genesis
|
||||
@ -138,9 +138,9 @@ var testNet3GenesisBlock = wire.MsgBlock{
|
||||
Version: 1,
|
||||
ParentHashes: []daghash.Hash{},
|
||||
MerkleRoot: genesisMerkleRoot,
|
||||
Timestamp: time.Unix(0x5c238413, 0),
|
||||
Timestamp: time.Unix(0x5c34b3ba, 0),
|
||||
Bits: 0x207fffff,
|
||||
Nonce: 0x00000001,
|
||||
Nonce: 0xdffffffffffffff9,
|
||||
},
|
||||
Transactions: []*wire.MsgTx{&genesisCoinbaseTx},
|
||||
}
|
||||
@ -148,10 +148,10 @@ var testNet3GenesisBlock = wire.MsgBlock{
|
||||
// simNetGenesisHash is the hash of the first block in the block chain for the
|
||||
// simulation test network.
|
||||
var simNetGenesisHash = daghash.Hash([daghash.HashSize]byte{ // Make go vet happy.
|
||||
0x34, 0x16, 0x17, 0x85, 0x5d, 0xf7, 0x79, 0xde,
|
||||
0xdc, 0x37, 0xf0, 0x57, 0x93, 0x9d, 0x6f, 0x22,
|
||||
0xe5, 0xff, 0xa0, 0x3e, 0xc7, 0x3e, 0x50, 0xf5,
|
||||
0xa1, 0x2a, 0x0a, 0x2e, 0x48, 0x05, 0xc2, 0x47,
|
||||
0xca, 0xd9, 0x5f, 0x65, 0x44, 0xd4, 0x2f, 0x08,
|
||||
0x23, 0x22, 0x93, 0x4c, 0x07, 0xd9, 0xa4, 0xc0,
|
||||
0x1a, 0x51, 0x77, 0xf6, 0x13, 0x7c, 0x06, 0x8b,
|
||||
0xd2, 0x6d, 0xe1, 0x38, 0xea, 0x12, 0xcd, 0x4a,
|
||||
})
|
||||
|
||||
// simNetGenesisMerkleRoot is the hash of the first transaction in the genesis
|
||||
@ -166,9 +166,9 @@ var simNetGenesisBlock = wire.MsgBlock{
|
||||
Version: 1,
|
||||
ParentHashes: []daghash.Hash{},
|
||||
MerkleRoot: genesisMerkleRoot,
|
||||
Timestamp: time.Unix(0x5c238413, 0),
|
||||
Timestamp: time.Unix(0x5c34b3ba, 0),
|
||||
Bits: 0x207fffff,
|
||||
Nonce: 0x00000001,
|
||||
Nonce: 0xdffffffffffffff9,
|
||||
},
|
||||
Transactions: []*wire.MsgTx{&genesisCoinbaseTx},
|
||||
}
|
||||
|
@ -121,14 +121,14 @@ func TestSimNetGenesisBlock(t *testing.T) {
|
||||
// genesisBlockBytes are the wire encoded bytes for the genesis block of the
|
||||
// main network as of protocol version 60002.
|
||||
var genesisBlockBytes = []byte{
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0x6e, 0xd7, /* |.....yn.| */
|
||||
0x12, 0x58, 0xea, 0x3f, 0x88, 0xa1, 0xfa, 0x7a, /* |.X.?...z| */
|
||||
0x67, 0x2b, 0x68, 0x76, 0x6b, 0x39, 0x6b, 0x7d, /* |g+hvk9k}| */
|
||||
0x15, 0x6b, 0x1a, 0xb1, 0x96, 0xe2, 0x17, 0x2c, /* |.k.....,| */
|
||||
0x4a, 0x6a, 0xad, 0x72, 0x96, 0x13, 0x84, 0x23, /* |Jj.r...#| */
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x7c, 0x26, /* |.....Z|&| */
|
||||
0x54, 0x0d, 0x46, 0x6b, 0x5f, 0x4a, 0x2c, 0x29, /* |T.Fk_J,)| */
|
||||
0xff, 0x2f, 0xa5, 0xa0, 0xad, 0x9c, 0xd2, 0x4f, /* |./.....O| */
|
||||
0x6e, 0xa9, 0x16, 0xfa, 0xb5, 0x52, 0x5e, 0x40, /* |n....R^@| */
|
||||
0xa2, 0x69, 0xb6, 0x8d, 0x5c, 0xba, 0xb3, 0x34, /* |.i..\..4| */
|
||||
0x5c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, /* |\.......| */
|
||||
0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* | .......| */
|
||||
0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, /* |........| */
|
||||
0x20, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* | .......| */
|
||||
0xdf, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, /* |........| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
|
||||
@ -155,20 +155,22 @@ var genesisBlockBytes = []byte{
|
||||
0xf7, 0xba, 0x0b, 0x8d, 0x57, 0x8a, 0x4c, 0x70, /* |....W.Lp| */
|
||||
0x2b, 0x6b, 0xf1, 0x1d, 0x5f, 0xac, 0x00, 0x00, /* |+k.._...| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, /* |........| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |......| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
|
||||
0x00, 0x00, /* |..| */
|
||||
}
|
||||
|
||||
// regTestGenesisBlockBytes are the wire encoded bytes for the genesis block of
|
||||
// the regression test network as of protocol version 60002.
|
||||
var regTestGenesisBlockBytes = []byte{
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0x6e, 0xd7, /* |.....yn.| */
|
||||
0x12, 0x58, 0xea, 0x3f, 0x88, 0xa1, 0xfa, 0x7a, /* |.X.?...z| */
|
||||
0x67, 0x2b, 0x68, 0x76, 0x6b, 0x39, 0x6b, 0x7d, /* |g+hvk9k}| */
|
||||
0x15, 0x6b, 0x1a, 0xb1, 0x96, 0xe2, 0x17, 0x2c, /* |.k.....,| */
|
||||
0x4a, 0x6a, 0xad, 0x72, 0x96, 0x13, 0x84, 0x23, /* |Jj.r...#| */
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x7c, 0x26, /* |.....Z|&| */
|
||||
0x54, 0x0d, 0x46, 0x6b, 0x5f, 0x4a, 0x2c, 0x29, /* |T.Fk_J,)| */
|
||||
0xff, 0x2f, 0xa5, 0xa0, 0xad, 0x9c, 0xd2, 0x4f, /* |./.....O| */
|
||||
0x6e, 0xa9, 0x16, 0xfa, 0xb5, 0x52, 0x5e, 0x40, /* |n....R^@| */
|
||||
0xa2, 0x69, 0xb6, 0x8d, 0x5c, 0xba, 0xb3, 0x34, /* |.i..\..4| */
|
||||
0x5c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, /* |\.......| */
|
||||
0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* | .......| */
|
||||
0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, /* |........| */
|
||||
0x20, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* | .......| */
|
||||
0xdf, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, /* |........| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
|
||||
@ -195,20 +197,22 @@ var regTestGenesisBlockBytes = []byte{
|
||||
0xf7, 0xba, 0x0b, 0x8d, 0x57, 0x8a, 0x4c, 0x70, /* |....W.Lp| */
|
||||
0x2b, 0x6b, 0xf1, 0x1d, 0x5f, 0xac, 0x00, 0x00, /* |+k.._...| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, /* |........| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |......| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
|
||||
0x00, 0x00, /* |..| */
|
||||
}
|
||||
|
||||
// testNet3GenesisBlockBytes are the wire encoded bytes for the genesis block of
|
||||
// the test network (version 3) as of protocol version 60002.
|
||||
var testNet3GenesisBlockBytes = []byte{
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0x6e, 0xd7, /* |.....yn.| */
|
||||
0x12, 0x58, 0xea, 0x3f, 0x88, 0xa1, 0xfa, 0x7a, /* |.X.?...z| */
|
||||
0x67, 0x2b, 0x68, 0x76, 0x6b, 0x39, 0x6b, 0x7d, /* |g+hvk9k}| */
|
||||
0x15, 0x6b, 0x1a, 0xb1, 0x96, 0xe2, 0x17, 0x2c, /* |.k.....,| */
|
||||
0x4a, 0x6a, 0xad, 0x72, 0x96, 0x13, 0x84, 0x23, /* |Jj.r...#| */
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x7c, 0x26, /* |.....Z|&| */
|
||||
0x54, 0x0d, 0x46, 0x6b, 0x5f, 0x4a, 0x2c, 0x29, /* |T.Fk_J,)| */
|
||||
0xff, 0x2f, 0xa5, 0xa0, 0xad, 0x9c, 0xd2, 0x4f, /* |./.....O| */
|
||||
0x6e, 0xa9, 0x16, 0xfa, 0xb5, 0x52, 0x5e, 0x40, /* |n....R^@| */
|
||||
0xa2, 0x69, 0xb6, 0x8d, 0x5c, 0xba, 0xb3, 0x34, /* |.i..\..4| */
|
||||
0x5c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, /* |\.......| */
|
||||
0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* | .......| */
|
||||
0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, /* |........| */
|
||||
0x20, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* | .......| */
|
||||
0xdf, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, /* |........| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
|
||||
@ -235,20 +239,22 @@ var testNet3GenesisBlockBytes = []byte{
|
||||
0xf7, 0xba, 0x0b, 0x8d, 0x57, 0x8a, 0x4c, 0x70, /* |....W.Lp| */
|
||||
0x2b, 0x6b, 0xf1, 0x1d, 0x5f, 0xac, 0x00, 0x00, /* |+k.._...| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, /* |........| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |......| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
|
||||
0x00, 0x00, /* |..| */
|
||||
}
|
||||
|
||||
// simNetGenesisBlockBytes are the wire encoded bytes for the genesis block of
|
||||
// the simulation test network as of protocol version 70002.
|
||||
var simNetGenesisBlockBytes = []byte{
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0x6e, 0xd7, /* |.....yn.| */
|
||||
0x12, 0x58, 0xea, 0x3f, 0x88, 0xa1, 0xfa, 0x7a, /* |.X.?...z| */
|
||||
0x67, 0x2b, 0x68, 0x76, 0x6b, 0x39, 0x6b, 0x7d, /* |g+hvk9k}| */
|
||||
0x15, 0x6b, 0x1a, 0xb1, 0x96, 0xe2, 0x17, 0x2c, /* |.k.....,| */
|
||||
0x4a, 0x6a, 0xad, 0x72, 0x96, 0x13, 0x84, 0x23, /* |Jj.r...#| */
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x7c, 0x26, /* |.....Z|&| */
|
||||
0x54, 0x0d, 0x46, 0x6b, 0x5f, 0x4a, 0x2c, 0x29, /* |T.Fk_J,)| */
|
||||
0xff, 0x2f, 0xa5, 0xa0, 0xad, 0x9c, 0xd2, 0x4f, /* |./.....O| */
|
||||
0x6e, 0xa9, 0x16, 0xfa, 0xb5, 0x52, 0x5e, 0x40, /* |n....R^@| */
|
||||
0xa2, 0x69, 0xb6, 0x8d, 0x5c, 0xba, 0xb3, 0x34, /* |.i..\..4| */
|
||||
0x5c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, /* |\.......| */
|
||||
0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* | .......| */
|
||||
0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, /* |........| */
|
||||
0x20, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* | .......| */
|
||||
0xdf, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, /* |........| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
|
||||
@ -275,5 +281,7 @@ var simNetGenesisBlockBytes = []byte{
|
||||
0xf7, 0xba, 0x0b, 0x8d, 0x57, 0x8a, 0x4c, 0x70, /* |....W.Lp| */
|
||||
0x2b, 0x6b, 0xf1, 0x1d, 0x5f, 0xac, 0x00, 0x00, /* |+k.._...| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, /* |........| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |......| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
|
||||
0x00, 0x00, /* |..| */
|
||||
}
|
||||
|
@ -175,5 +175,5 @@ func Example_blockStorageAndRetrieval() {
|
||||
fmt.Printf("Serialized block size: %d bytes\n", len(loadedBlockBytes))
|
||||
|
||||
// Output:
|
||||
// Serialized block size: 278 bytes
|
||||
// Serialized block size: 290 bytes
|
||||
}
|
||||
|
BIN
database/testdata/blocks1-256.bz2
vendored
BIN
database/testdata/blocks1-256.bz2
vendored
Binary file not shown.
@ -659,10 +659,10 @@ func (mp *TxPool) maybeAcceptTransaction(tx *util.Tx, isNew, rateLimit, rejectDu
|
||||
|
||||
// Check that transaction does not overuse GAS
|
||||
msgTx := tx.MsgTx()
|
||||
if msgTx.SubNetworkID == 0 {
|
||||
if msgTx.SubNetworkID == wire.SubNetworkSupportsAll {
|
||||
return nil, nil, txRuleError(wire.RejectInvalid, "Subnetwork 0 is not permited in transaction")
|
||||
} else if msgTx.SubNetworkID != wire.SubNetworkDAGCoin {
|
||||
gasLimit, err := mp.cfg.DAG.GasLimit(msgTx.SubNetworkID)
|
||||
gasLimit, err := mp.cfg.DAG.GasLimit(&msgTx.SubNetworkID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/daglabs/btcd/util/subnetworkid"
|
||||
"math"
|
||||
"reflect"
|
||||
"runtime"
|
||||
@ -155,11 +156,11 @@ func (p *poolHarness) CreateCoinbaseTx(blockHeight int32, numOutputs uint32) (*u
|
||||
return util.NewTx(tx), nil
|
||||
}
|
||||
|
||||
// CreateSignedTxForSubnetwork creates a new signed transaction that consumes the provided
|
||||
// CreateSignedTxForSubNetwork creates a new signed transaction that consumes the provided
|
||||
// inputs and generates the provided number of outputs by evenly splitting the
|
||||
// total input amount. All outputs will be to the payment script associated
|
||||
// with the harness and all inputs are assumed to do the same.
|
||||
func (p *poolHarness) CreateSignedTxForSubnetwork(inputs []spendableOutpoint, numOutputs uint32, subnetworkID uint64, gas uint64) (*util.Tx, error) {
|
||||
func (p *poolHarness) CreateSignedTxForSubNetwork(inputs []spendableOutpoint, numOutputs uint32, subNetworkID *subnetworkid.SubNetworkID, gas uint64) (*util.Tx, error) {
|
||||
// Calculate the total input amount and split it amongst the requested
|
||||
// number of outputs.
|
||||
var totalInput util.Amount
|
||||
@ -170,7 +171,7 @@ func (p *poolHarness) CreateSignedTxForSubnetwork(inputs []spendableOutpoint, nu
|
||||
remainder := uint64(totalInput) - amountPerOutput*uint64(numOutputs)
|
||||
|
||||
tx := wire.NewMsgTx(wire.TxVersion)
|
||||
tx.SubNetworkID = subnetworkID
|
||||
tx.SubNetworkID = *subNetworkID
|
||||
tx.Gas = gas
|
||||
for _, input := range inputs {
|
||||
tx.AddTxIn(&wire.TxIn{
|
||||
@ -210,7 +211,7 @@ func (p *poolHarness) CreateSignedTxForSubnetwork(inputs []spendableOutpoint, nu
|
||||
// total input amount. All outputs will be to the payment script associated
|
||||
// with the harness and all inputs are assumed to do the same.
|
||||
func (p *poolHarness) CreateSignedTx(inputs []spendableOutpoint, numOutputs uint32) (*util.Tx, error) {
|
||||
return p.CreateSignedTxForSubnetwork(inputs, numOutputs, wire.SubNetworkDAGCoin, 0)
|
||||
return p.CreateSignedTxForSubNetwork(inputs, numOutputs, &wire.SubNetworkDAGCoin, 0)
|
||||
}
|
||||
|
||||
// CreateTxChain creates a chain of zero-fee transactions (each subsequent
|
||||
@ -1843,13 +1844,13 @@ func TestTransactionGas(t *testing.T) {
|
||||
// tc := &testContext{t, harness}
|
||||
|
||||
const gasLimit = 10000
|
||||
subnetworkID, err := blockdag.RegisterSubnetworkForTest(harness.txPool.cfg.DAG, gasLimit)
|
||||
subNetworkID, err := blockdag.RegisterSubNetworkForTest(harness.txPool.cfg.DAG, gasLimit)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to register network: %v", err)
|
||||
}
|
||||
|
||||
// Create valid transaction
|
||||
tx, err := harness.CreateSignedTxForSubnetwork(spendableOuts[:1], 1, subnetworkID, gasLimit)
|
||||
tx, err := harness.CreateSignedTxForSubNetwork(spendableOuts[:1], 1, subNetworkID, gasLimit)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create transaction: %v", err)
|
||||
}
|
||||
@ -1859,7 +1860,7 @@ func TestTransactionGas(t *testing.T) {
|
||||
}
|
||||
|
||||
// Create invalid transaction
|
||||
tx, err = harness.CreateSignedTxForSubnetwork(spendableOuts[1:], 1, subnetworkID, gasLimit+1)
|
||||
tx, err = harness.CreateSignedTxForSubNetwork(spendableOuts[1:], 1, subNetworkID, gasLimit+1)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create transaction: %v", err)
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"github.com/daglabs/btcd/dagconfig/daghash"
|
||||
"github.com/daglabs/btcd/txscript"
|
||||
"github.com/daglabs/btcd/util"
|
||||
"github.com/daglabs/btcd/util/subnetworkid"
|
||||
"github.com/daglabs/btcd/wire"
|
||||
)
|
||||
|
||||
@ -475,7 +476,7 @@ func (g *BlkTmplGenerator) NewBlockTemplate(payToAddress util.Address) (*BlockTe
|
||||
totalFees := uint64(0)
|
||||
|
||||
// Create map of GAS usage per subnetwork
|
||||
gasUsageMap := make(map[uint64]uint64)
|
||||
gasUsageMap := make(map[subnetworkid.SubNetworkID]uint64)
|
||||
|
||||
// Choose which transactions make it into the block.
|
||||
for priorityQueue.Len() > 0 {
|
||||
@ -485,23 +486,23 @@ func (g *BlkTmplGenerator) NewBlockTemplate(payToAddress util.Address) (*BlockTe
|
||||
tx := prioItem.tx
|
||||
|
||||
if tx.MsgTx().SubNetworkID != wire.SubNetworkDAGCoin {
|
||||
subnetwork := tx.MsgTx().SubNetworkID
|
||||
gasUsage, ok := gasUsageMap[subnetwork]
|
||||
subNetwork := tx.MsgTx().SubNetworkID
|
||||
gasUsage, ok := gasUsageMap[subNetwork]
|
||||
if !ok {
|
||||
gasUsage = 0
|
||||
}
|
||||
gasLimit, err := g.dag.GasLimit(subnetwork)
|
||||
gasLimit, err := g.dag.GasLimit(&subNetwork)
|
||||
if err != nil {
|
||||
log.Errorf("Cannot get GAS limit for subnetwork %v", subnetwork)
|
||||
log.Errorf("Cannot get GAS limit for subNetwork %v", subNetwork)
|
||||
continue
|
||||
}
|
||||
txGas := tx.MsgTx().Gas
|
||||
if gasLimit-gasUsage < txGas {
|
||||
log.Tracef("Transaction %v (GAS=%v) ignored because gas overusage (GASUsage=%v) in subnetwork %v (GASLimit=%v)",
|
||||
tx.MsgTx().TxHash, txGas, gasUsage, subnetwork, gasLimit)
|
||||
log.Tracef("Transaction %v (GAS=%v) ignored because gas overusage (GASUsage=%v) in subNetwork %v (GASLimit=%v)",
|
||||
tx.MsgTx().TxHash, txGas, gasUsage, subNetwork, gasLimit)
|
||||
continue
|
||||
}
|
||||
gasUsageMap[subnetwork] = gasUsage + txGas
|
||||
gasUsageMap[subNetwork] = gasUsage + txGas
|
||||
}
|
||||
|
||||
// Enforce maximum block size. Also check for overflow.
|
||||
@ -645,7 +646,7 @@ func (g *BlkTmplGenerator) NewBlockTemplate(payToAddress util.Address) (*BlockTe
|
||||
|
||||
// Sort transactions by subnetwork ID before building Merkle tree
|
||||
sort.Slice(blockTxns, func(i, j int) bool {
|
||||
return blockTxns[i].MsgTx().SubNetworkID < blockTxns[j].MsgTx().SubNetworkID
|
||||
return subnetworkid.Less(&blockTxns[i].MsgTx().SubNetworkID, &blockTxns[j].MsgTx().SubNetworkID)
|
||||
})
|
||||
|
||||
// Create a new block ready to be solved.
|
||||
|
@ -140,7 +140,7 @@ func TestCalcPriority(t *testing.T) {
|
||||
utxoSet: newUTXOSet([]*wire.MsgTx{commonSourceTx1},
|
||||
[]int32{7}),
|
||||
nextHeight: 169,
|
||||
want: 1.35e+10,
|
||||
want: 1.125e+10,
|
||||
},
|
||||
{
|
||||
name: "one height 100 input, prio tx height 169",
|
||||
@ -148,7 +148,7 @@ func TestCalcPriority(t *testing.T) {
|
||||
utxoSet: newUTXOSet([]*wire.MsgTx{commonSourceTx1},
|
||||
[]int32{100}),
|
||||
nextHeight: 169,
|
||||
want: 5.75e+09,
|
||||
want: 4.791666666666667e+09,
|
||||
},
|
||||
{
|
||||
name: "one height 7 input, prio tx height 100000",
|
||||
@ -156,7 +156,7 @@ func TestCalcPriority(t *testing.T) {
|
||||
utxoSet: newUTXOSet([]*wire.MsgTx{commonSourceTx1},
|
||||
[]int32{7}),
|
||||
nextHeight: 100000,
|
||||
want: 8.33275e+12,
|
||||
want: 6.943958333333333e+12,
|
||||
},
|
||||
{
|
||||
name: "one height 100 input, prio tx height 100000",
|
||||
@ -164,7 +164,7 @@ func TestCalcPriority(t *testing.T) {
|
||||
utxoSet: newUTXOSet([]*wire.MsgTx{commonSourceTx1},
|
||||
[]int32{100}),
|
||||
nextHeight: 100000,
|
||||
want: 8.325e+12,
|
||||
want: 6.9375e+12,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -889,7 +889,7 @@ func handleGenerate(s *Server, cmd interface{}, closeChan <-chan struct{}) (inte
|
||||
}
|
||||
}
|
||||
|
||||
if config.MainConfig().SubNetwork != wire.SubNetworkSupportsAll {
|
||||
if !config.MainConfig().SubNetwork.IsEqual(&wire.SubNetworkSupportsAll) {
|
||||
return nil, &btcjson.RPCError{
|
||||
Code: btcjson.ErrRPCInvalidRequest.Code,
|
||||
Message: "`generate` is not supported on partial nodes.",
|
||||
@ -2230,7 +2230,7 @@ func handleGetGenerate(s *Server, cmd interface{}, closeChan <-chan struct{}) (i
|
||||
|
||||
// handleGetHashesPerSec implements the getHashesPerSec command.
|
||||
func handleGetHashesPerSec(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||
if config.MainConfig().SubNetwork != wire.SubNetworkSupportsAll {
|
||||
if !config.MainConfig().SubNetwork.IsEqual(&wire.SubNetworkSupportsAll) {
|
||||
return nil, &btcjson.RPCError{
|
||||
Code: btcjson.ErrRPCInvalidRequest.Code,
|
||||
Message: "`getHashesPerSec` is not supported on partial nodes.",
|
||||
@ -2319,7 +2319,7 @@ func handleGetMempoolInfo(s *Server, cmd interface{}, closeChan <-chan struct{})
|
||||
// handleGetMiningInfo implements the getMiningInfo command. We only return the
|
||||
// fields that are not related to wallet functionality.
|
||||
func handleGetMiningInfo(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||
if config.MainConfig().SubNetwork != wire.SubNetworkSupportsAll {
|
||||
if !config.MainConfig().SubNetwork.IsEqual(&wire.SubNetworkSupportsAll) {
|
||||
return nil, &btcjson.RPCError{
|
||||
Code: btcjson.ErrRPCInvalidRequest.Code,
|
||||
Message: "`getMiningInfo` is not supported on partial nodes.",
|
||||
@ -2381,7 +2381,7 @@ func handleGetNetTotals(s *Server, cmd interface{}, closeChan <-chan struct{}) (
|
||||
// This command had been (possibly temporarily) dropped.
|
||||
// Originally it relied on height, which no longer makes sense.
|
||||
func handleGetNetworkHashPS(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||
if config.MainConfig().SubNetwork != wire.SubNetworkSupportsAll {
|
||||
if !config.MainConfig().SubNetwork.IsEqual(&wire.SubNetworkSupportsAll) {
|
||||
return nil, &btcjson.RPCError{
|
||||
Code: btcjson.ErrRPCInvalidRequest.Code,
|
||||
Message: "`getNetworkHashPS` is not supported on partial nodes.",
|
||||
@ -3286,7 +3286,7 @@ func handleSendRawTransaction(s *Server, cmd interface{}, closeChan <-chan struc
|
||||
|
||||
// handleSetGenerate implements the setGenerate command.
|
||||
func handleSetGenerate(s *Server, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||
if config.MainConfig().SubNetwork != wire.SubNetworkSupportsAll {
|
||||
if !config.MainConfig().SubNetwork.IsEqual(&wire.SubNetworkSupportsAll) {
|
||||
return nil, &btcjson.RPCError{
|
||||
Code: btcjson.ErrRPCInvalidRequest.Code,
|
||||
Message: "`setGenerate` is not supported on partial nodes.",
|
||||
|
@ -54,10 +54,10 @@ func TestBlock(t *testing.T) {
|
||||
|
||||
// Hashes for the transactions in Block100000.
|
||||
wantTxHashes := []string{
|
||||
"4f2a5f1e00034ed3222e0e7fae8485ad3154d40b21b1c1b64ec74ce389a1bb1d",
|
||||
"cdd164e1b3c910e1b54349d442d26541830d0551a15c8b2e202aa7f96ccf3b32",
|
||||
"7fb0543009c39a12a0e5b3c23f157c9152f9e956412a825d296d1e3826dcf81c",
|
||||
"ba611a9e39e784e51ea9efe66453de7a0355deae454f63c526a1938a58f683fc",
|
||||
"171090dd8ab478a2c4499858abd5d9b10e173b659bab5d5acca68c7dcb4c519e",
|
||||
"fc9100986f2a188ccffe206a4c013aaa0c7442898b2f58d474f0b4f534600e0b",
|
||||
"42ef8bcc302b4a92d479c02c4bf6cb154f26ad9915433da7fb102f6fd135b5c3",
|
||||
"c8eeef60be812de9982d066be027fee93f2c226c840670424a413fbd66ad36dd",
|
||||
}
|
||||
|
||||
// Create a new block to nuke all cached data.
|
||||
@ -146,10 +146,10 @@ func TestBlock(t *testing.T) {
|
||||
|
||||
// Transaction offsets and length for the transaction in Block100000.
|
||||
wantTxLocs := []wire.TxLoc{
|
||||
{TxStart: 122, TxLen: 151},
|
||||
{TxStart: 273, TxLen: 275},
|
||||
{TxStart: 548, TxLen: 273},
|
||||
{TxStart: 821, TxLen: 241},
|
||||
{TxStart: 122, TxLen: 163},
|
||||
{TxStart: 285, TxLen: 287},
|
||||
{TxStart: 572, TxLen: 285},
|
||||
{TxStart: 857, TxLen: 253},
|
||||
}
|
||||
|
||||
// Ensure the transaction location information is accurate.
|
||||
|
@ -255,7 +255,7 @@ func TestFilterBloomMatch(t *testing.T) {
|
||||
"3D11000000001976A91404943FDD508053C75000106D3BC6" +
|
||||
"E2754DBCFF1988AC2F15DE00000000001976A914A266436D" +
|
||||
"2965547608B9E15D9032A7B9D64FA43188AC000000000000" +
|
||||
"00000100000000000000"
|
||||
"00000100000000000000000000000000000000000000"
|
||||
strBytes, err := hex.DecodeString(str)
|
||||
if err != nil {
|
||||
t.Errorf("TestFilterBloomMatch DecodeString failure: %v", err)
|
||||
@ -266,18 +266,24 @@ func TestFilterBloomMatch(t *testing.T) {
|
||||
t.Errorf("TestFilterBloomMatch NewTxFromBytes failure: %v", err)
|
||||
return
|
||||
}
|
||||
spendingTxStr := "0100000001F66914B25A46137FB0551E95CCE775254B8711" +
|
||||
"D01D7D258C119396E57E105622000000008C493046022100" +
|
||||
"DA0DC6AECEFE1E06EFDF05773757DEB168820930E3B0D03F" +
|
||||
"46F5FCF150BF990C022100D25B5C87040076E4F253F8262E" +
|
||||
"763E2DD51E7FF0BE157727C4BC42807F17BD39014104E6C2" +
|
||||
"6EF67DC610D2CD192484789A6CF9AEA9930B944B7E2DB534" +
|
||||
"2B9D9E5B9FF79AFF9A2EE1978DD7FD01DFC522EE02283D3B" +
|
||||
"06A9D03ACF8096968D7DBB0F9178FFFFFFFFFFFFFFFF028B" +
|
||||
"A7940E000000001976A914BADEECFDEF0507247FC8F74241" +
|
||||
"D73BC039972D7B88AC4094A802000000001976A914C10932" +
|
||||
"483FEC93ED51F5FE95E72559F2CC7043F988AC0000000000" +
|
||||
"0000000100000000000000"
|
||||
spendingTxStr := "0100000001D25EE298643F1793383A12" +
|
||||
"8F8E70FF33932B6532511CC6E7556D03" +
|
||||
"3370AB7CB7000000008C493046022100" +
|
||||
"DA0DC6AECEFE1E06EFDF05773757DEB1" +
|
||||
"68820930E3B0D03F46F5FCF150BF990C" +
|
||||
"022100D25B5C87040076E4F253F8262E" +
|
||||
"763E2DD51E7FF0BE157727C4BC42807F" +
|
||||
"17BD39014104E6C26EF67DC610D2CD19" +
|
||||
"2484789A6CF9AEA9930B944B7E2DB534" +
|
||||
"2B9D9E5B9FF79AFF9A2EE1978DD7FD01" +
|
||||
"DFC522EE02283D3B06A9D03ACF809696" +
|
||||
"8D7DBB0F9178FFFFFFFFFFFFFFFF028B" +
|
||||
"A7940E000000001976A914BADEECFDEF" +
|
||||
"0507247FC8F74241D73BC039972D7B88" +
|
||||
"AC4094A802000000001976A914C10932" +
|
||||
"483FEC93ED51F5FE95E72559F2CC7043" +
|
||||
"F988AC00000000000000000100000000" +
|
||||
"000000000000000000000000000000"
|
||||
spendingTxBytes, err := hex.DecodeString(spendingTxStr)
|
||||
if err != nil {
|
||||
t.Errorf("TestFilterBloomMatch DecodeString failed to decode spendingTxStr: %v", err)
|
||||
@ -291,7 +297,7 @@ func TestFilterBloomMatch(t *testing.T) {
|
||||
}
|
||||
|
||||
f := bloom.NewFilter(10, 0, 0.000001, wire.BloomUpdateAll)
|
||||
inputStr := "2256107ee59693118c257d1dd011874b2575e7cc951e55b07f13465ab21469f6" // byte-reversed tx hash
|
||||
inputStr := "b77cab7033036d55e7c61c5132652b9333ff708e8f123a3893173f6498e25ed2" // byte-reversed tx hash
|
||||
hash, err := daghash.NewHashFromStr(inputStr)
|
||||
if err != nil {
|
||||
t.Errorf("TestFilterBloomMatch NewHashFromStr failed: %v\n", err)
|
||||
@ -303,7 +309,7 @@ func TestFilterBloomMatch(t *testing.T) {
|
||||
}
|
||||
|
||||
f = bloom.NewFilter(10, 0, 0.000001, wire.BloomUpdateAll)
|
||||
inputStr = "f66914b25a46137fb0551e95cce775254b8711d01d7d258c119396e57e105622" // non-reversed tx hash
|
||||
inputStr = "d25ee298643f1793383a128f8e70ff33932b6532511cc6e7556d033370ab7cb7" // non-reversed tx hash
|
||||
hashBytes, err := hex.DecodeString(inputStr)
|
||||
if err != nil {
|
||||
t.Errorf("TestFilterBloomMatch DecodeString failed: %v\n", err)
|
||||
@ -511,7 +517,8 @@ func TestFilterInsertP2PubKeyOnly(t *testing.T) {
|
||||
0xE0, 0xD8, 0x11, 0x13, 0xC3, 0x80, 0x74, 0x20, 0xCE, 0x13, 0xAD,
|
||||
0x13, 0x57, 0x23, 0x1A, 0x22, 0x52, 0x24, 0x7D, 0x97, 0xA4, 0x6A,
|
||||
0x91, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x01, 0x00, 0x00, 0x00, 0x01, 0xBC, 0xAD, 0x20, 0xA6, 0xA2, 0x98, // Txs[1]
|
||||
0x27, 0xD1, 0x42, 0x4F, 0x08, 0x98, 0x92, 0x55, 0x12, 0x0B, 0xF7,
|
||||
@ -531,7 +538,8 @@ func TestFilterInsertP2PubKeyOnly(t *testing.T) {
|
||||
0x00, 0x19, 0x76, 0xA9, 0x14, 0x1B, 0x8D, 0xD1, 0x3B, 0x99, 0x4B,
|
||||
0xCF, 0xC7, 0x87, 0xB3, 0x2A, 0xEA, 0xDF, 0x58, 0xCC, 0xB3, 0x61,
|
||||
0x5C, 0xBD, 0x54, 0x88, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x03, 0xFD, 0xAC, 0xF9, 0xB3, 0xEB, 0x07, // Txs[2]
|
||||
0x74, 0x12, 0xE7, 0xA9, 0x68, 0xD2, 0xE4, 0xF1, 0x1B, 0x9A, 0x9D,
|
||||
0xEE, 0x31, 0x2D, 0x66, 0x61, 0x87, 0xED, 0x77, 0xEE, 0x7D, 0x26,
|
||||
@ -575,7 +583,8 @@ func TestFilterInsertP2PubKeyOnly(t *testing.T) {
|
||||
0xB5, 0x51, 0x41, 0xD0, 0x97, 0xEA, 0x5D, 0xF7, 0xA0, 0xED, 0x33,
|
||||
0x0C, 0xF7, 0x94, 0x37, 0x6E, 0x53, 0xEC, 0x8D, 0x88, 0xAC, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x04, 0x5B, 0xF0, 0xE2, 0x14, 0xAA, 0x40, // Txs[3]
|
||||
0x69, 0xA3, 0xE7, 0x92, 0xEC, 0xEE, 0x1E, 0x1B, 0xF0, 0xC1, 0xD3,
|
||||
0x97, 0xCD, 0xE8, 0xDD, 0x08, 0x13, 0x8F, 0x4B, 0x72, 0xA0, 0x06,
|
||||
@ -648,7 +657,8 @@ func TestFilterInsertP2PubKeyOnly(t *testing.T) {
|
||||
0xEF, 0xD8, 0x0D, 0x99, 0x17, 0x9F, 0x4F, 0x4F, 0xF6, 0xF4, 0xDD,
|
||||
0x0A, 0x00, 0x7D, 0x01, 0x8C, 0x38, 0x5D, 0x21,
|
||||
0x88, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x01, 0x83, 0x45, 0x37, 0xB2, 0xF1, 0xCE, // Txs[4]
|
||||
0x8E, 0xF9, 0x37, 0x3A, 0x25, 0x8E, 0x10, 0x54, 0x5C, 0xE5, 0xA5,
|
||||
0x0B, 0x75, 0x8D, 0xF6, 0x16, 0xCD, 0x43, 0x56, 0xE0, 0x03, 0x25,
|
||||
@ -673,7 +683,8 @@ func TestFilterInsertP2PubKeyOnly(t *testing.T) {
|
||||
0x00, 0x19, 0x76, 0xA9, 0x14, 0xA8, 0x4E, 0x27, 0x29, 0x33, 0xAA,
|
||||
0xF8, 0x7E, 0x17, 0x15, 0xD7, 0x78, 0x6C, 0x51, 0xDF, 0xAE, 0xB5,
|
||||
0xB6, 0x5A, 0x6F, 0x88, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x01, 0x43, 0xAC, 0x81, 0xC8, 0xE6, 0xF6, // Txs[5]
|
||||
0xEF, 0x30, 0x7D, 0xFE, 0x17, 0xF3, 0xD9, 0x06, 0xD9, 0x99, 0xE2,
|
||||
0x3E, 0x01, 0x89, 0xFD, 0xA8, 0x38, 0xC5, 0x51, 0x0D, 0x85, 0x09,
|
||||
@ -699,6 +710,8 @@ func TestFilterInsertP2PubKeyOnly(t *testing.T) {
|
||||
0x00, 0xD7, 0x96, 0x8B, 0x34, 0x05, 0xC0, 0x34, 0xAD, 0xC3, 0x8D,
|
||||
0x4D, 0x8F, 0xB9, 0xBD, 0x88, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x02, 0x48, 0xCC, 0x91, 0x75, 0x01, 0xEA, // Txs[6]
|
||||
0x5C, 0x55, 0xF4, 0xA8, 0xD2, 0x00, 0x9C, 0x05, 0x67, 0xC4, 0x0C,
|
||||
0xFE, 0x03, 0x7C, 0x2E, 0x71, 0xAF, 0x01, 0x7D, 0x0A, 0x45, 0x2F,
|
||||
@ -738,7 +751,8 @@ func TestFilterInsertP2PubKeyOnly(t *testing.T) {
|
||||
0x82, 0x2F, 0x1A, 0xD5, 0x80, 0xB0, 0x43, 0xC7, 0xB3, 0xDF, 0x2E,
|
||||
0x40, 0x0F, 0x86, 0x99, 0xEB, 0x48, 0x88, 0xAC, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00,
|
||||
}
|
||||
block, err := util.NewBlockFromBytes(blockBytes)
|
||||
if err != nil {
|
||||
@ -772,7 +786,7 @@ func TestFilterInsertP2PubKeyOnly(t *testing.T) {
|
||||
_, _ = bloom.NewMerkleBlock(block, f)
|
||||
|
||||
// We should match the generation pubkey
|
||||
inputStr = "807014abe7988704c8097b6ea882489cb1dc54daff96947eab9f6c04f2271252" //1st tx hash
|
||||
inputStr = "042aaac8c54b07f1e729e01d38b1fb26c6d595ed5920b856faf4070db79ce933" //0st tx hash
|
||||
hash, err := daghash.NewHashFromStr(inputStr)
|
||||
if err != nil {
|
||||
t.Errorf("TestMerkleBlockP2PubKeyOnly NewHashFromStr failed: %v", err)
|
||||
|
@ -42,7 +42,8 @@ func TestMerkleBlock3(t *testing.T) {
|
||||
0x4C, 0x74, 0xFB, 0xCC, 0xFD, 0x4F, 0x49, 0x63, 0x9C, 0xF1, 0xBD,
|
||||
0xC9, 0x4A, 0x56, 0x72, 0xBB, 0x15, 0xAD, 0x5D, 0x4C, 0xAC, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
}
|
||||
|
||||
blk, err := util.NewBlockFromBytes(blockBytes)
|
||||
@ -65,22 +66,22 @@ func TestMerkleBlock3(t *testing.T) {
|
||||
mBlock, _ := bloom.NewMerkleBlock(blk, f)
|
||||
|
||||
want := []byte{
|
||||
0x01, 0x00, 0x00, 0x00, 0x01, 0x79, 0xcd, 0xa8,
|
||||
0x56, 0xb1, 0x43, 0xd9, 0xdb, 0x2c, 0x1c, 0xaf,
|
||||
0xf0, 0x1d, 0x1a, 0xec, 0xc8, 0x63, 0x0d, 0x30,
|
||||
0x62, 0x5d, 0x10, 0xe8, 0xb4, 0xb8, 0xb0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x0c, 0xc0,
|
||||
0x69, 0xd6, 0xa3, 0xe3, 0x3e, 0x3f, 0xf8, 0x4a,
|
||||
0x5c, 0x41, 0xd9, 0xd3, 0xfe, 0xbe, 0x7c, 0x77,
|
||||
0x0f, 0xdc, 0xc9, 0x6b, 0x2c, 0x3f, 0xf6, 0x0a,
|
||||
0xbe, 0x18, 0x4f, 0x19, 0x63, 0x67, 0x29, 0x1b,
|
||||
0x4d, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x86, 0x04,
|
||||
0x1b, 0x8f, 0xa4, 0x5d, 0x63, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xaa, 0xda,
|
||||
0x38, 0x18, 0x2c, 0x17, 0xd8, 0x41, 0x3b, 0xd2,
|
||||
0xba, 0xd3, 0x16, 0x26, 0xb0, 0x96, 0x84, 0x6f,
|
||||
0x6b, 0xd4, 0xc4, 0xd3, 0xa6, 0x64, 0x45, 0x78,
|
||||
0x62, 0x5a, 0x23, 0xd4, 0x69, 0x92, 0x01, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x01, 0x79, 0xCD, 0xA8,
|
||||
0x56, 0xB1, 0x43, 0xD9, 0xDB, 0x2C, 0x1C, 0xAF,
|
||||
0xF0, 0x1D, 0x1A, 0xEC, 0xC8, 0x63, 0x0D, 0x30,
|
||||
0x62, 0x5D, 0x10, 0xE8, 0xB4, 0xB8, 0xB0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xB5, 0x0C, 0xC0,
|
||||
0x69, 0xD6, 0xA3, 0xE3, 0x3E, 0x3F, 0xF8, 0x4A,
|
||||
0x5C, 0x41, 0xD9, 0xD3, 0xFE, 0xBE, 0x7C, 0x77,
|
||||
0x0F, 0xDC, 0xC9, 0x6B, 0x2C, 0x3F, 0xF6, 0x0A,
|
||||
0xBE, 0x18, 0x4F, 0x19, 0x63, 0x67, 0x29, 0x1B,
|
||||
0x4D, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x86, 0x04,
|
||||
0x1B, 0x8F, 0xA4, 0x5D, 0x63, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x33, 0xB0,
|
||||
0x08, 0x73, 0xD7, 0xDE, 0x86, 0xF3, 0x9E, 0x37,
|
||||
0x06, 0x03, 0xB4, 0x75, 0xB4, 0xAC, 0xB4, 0x67,
|
||||
0xD3, 0x98, 0x3D, 0x2B, 0x9E, 0xE5, 0x35, 0x83,
|
||||
0x1A, 0xA4, 0xEC, 0xD5, 0x76, 0x18, 0x01, 0x00,
|
||||
}
|
||||
t.Log(spew.Sdump(want))
|
||||
if err != nil {
|
||||
|
@ -223,7 +223,7 @@ func TestMinPrioritySelector(t *testing.T) {
|
||||
var (
|
||||
// should be two outpoints, with 1st one having 0.035BTC value.
|
||||
testSimpleCoinNumConfs = int64(1)
|
||||
testSimpleCoinTxHash = "df280b66ce73fbd3713fe280e24bfa8bb21a7ccdfc81829d48bf1e16f8226310"
|
||||
testSimpleCoinTxHash = "8b6cefebd8a9b3ec28e9195b852edc306bc7d6b582bd5c8b74b602bbed4124b8"
|
||||
testSimpleCoinTxHex = "0100000001A214A110F79E4ABE073865EA5B3745C6E82C91" +
|
||||
"3BAD44BE70652804A5E4003B0A010000008C493046022100" +
|
||||
"EDD18A69664EFA57264BE207100C203E6CADE1888CBB88A0" +
|
||||
@ -235,7 +235,7 @@ var (
|
||||
"673500000000001976A914686DD149A79B4A559D561FBC39" +
|
||||
"6D3E3C6628B98D88ACE86EF102000000001976A914AC3F99" +
|
||||
"5655E81B875B38B64351D6F896DDBFC68588AC0000000000" +
|
||||
"000000010000000000000000"
|
||||
"000000010000000000000000000000000000000000000000"
|
||||
testSimpleCoinTxValue0 = util.Amount(3500000)
|
||||
testSimpleCoinTxValueAge0 = int64(testSimpleCoinTxValue0) * testSimpleCoinNumConfs
|
||||
testSimpleCoinTxPkScript0Hex = "76a914686dd149a79b4a559d561fbc396d3e3c6628b98d88ac"
|
||||
|
198
util/subnetworkid/subnetworkid.go
Normal file
198
util/subnetworkid/subnetworkid.go
Normal file
@ -0,0 +1,198 @@
|
||||
// Copyright (c) 2013-2016 The btcsuite developers
|
||||
// Copyright (c) 2015 The Decred developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package subnetworkid
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// IDLength of array used to store the sub-network ID. See SubNetworkID.
|
||||
const IDLength = 20
|
||||
|
||||
// MaxStringSize is the maximum length of a SubNetworkID string.
|
||||
const MaxStringSize = IDLength * 2
|
||||
|
||||
// ErrIDStrSize describes an error that indicates the caller specified an ID
|
||||
// string that has too many characters.
|
||||
var ErrIDStrSize = fmt.Errorf("max ID string length is %v bytes", MaxStringSize)
|
||||
|
||||
// SubNetworkID is used in several of the bitcoin messages and common structures. It
|
||||
// typically represents ripmed160(sha256(data)).
|
||||
type SubNetworkID [IDLength]byte
|
||||
|
||||
// String returns the SubNetworkID as the hexadecimal string of the byte-reversed
|
||||
// hash.
|
||||
func (id SubNetworkID) String() string {
|
||||
for i := 0; i < IDLength/2; i++ {
|
||||
id[i], id[IDLength-1-i] = id[IDLength-1-i], id[i]
|
||||
}
|
||||
return hex.EncodeToString(id[:])
|
||||
}
|
||||
|
||||
// Strings returns a slice of strings representing the IDs in the given slice of IDs
|
||||
func Strings(ids []SubNetworkID) []string {
|
||||
strings := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
strings[i] = id.String()
|
||||
}
|
||||
|
||||
return strings
|
||||
}
|
||||
|
||||
// CloneBytes returns a copy of the bytes which represent the ID as a byte
|
||||
// slice.
|
||||
//
|
||||
// NOTE: It is generally cheaper to just slice the ID directly thereby reusing
|
||||
// the same bytes rather than calling this method.
|
||||
func (id *SubNetworkID) CloneBytes() []byte {
|
||||
newID := make([]byte, IDLength)
|
||||
copy(newID, id[:])
|
||||
|
||||
return newID
|
||||
}
|
||||
|
||||
// SetBytes sets the bytes which represent the ID. An error is returned if
|
||||
// the number of bytes passed in is not IDLength.
|
||||
func (id *SubNetworkID) SetBytes(newID []byte) error {
|
||||
nhlen := len(newID)
|
||||
if nhlen != IDLength {
|
||||
return fmt.Errorf("invalid ID length of %v, want %v", nhlen,
|
||||
IDLength)
|
||||
}
|
||||
copy(id[:], newID)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsEqual returns true if target is the same as ID.
|
||||
func (id *SubNetworkID) IsEqual(target *SubNetworkID) bool {
|
||||
if id == nil && target == nil {
|
||||
return true
|
||||
}
|
||||
if id == nil || target == nil {
|
||||
return false
|
||||
}
|
||||
return *id == *target
|
||||
}
|
||||
|
||||
// AreEqual returns true if both slices contain the same IDs.
|
||||
// Either slice must not contain duplicates.
|
||||
func AreEqual(first []SubNetworkID, second []SubNetworkID) bool {
|
||||
if len(first) != len(second) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := range first {
|
||||
if first[i] != second[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// New returns a new ID from a byte slice. An error is returned if
|
||||
// the number of bytes passed in is not IDLength.
|
||||
func New(newID []byte) (*SubNetworkID, error) {
|
||||
var sh SubNetworkID
|
||||
err := sh.SetBytes(newID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &sh, err
|
||||
}
|
||||
|
||||
// NewFromStr creates a SubNetworkID from a string. The string should be
|
||||
// the hexadecimal string of a byte-reversed hash, but any missing characters
|
||||
// result in zero padding at the end of the SubNetworkID.
|
||||
func NewFromStr(id string) (*SubNetworkID, error) {
|
||||
ret := new(SubNetworkID)
|
||||
err := Decode(ret, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// Decode decodes the byte-reversed hexadecimal string encoding of a SubNetworkID to a
|
||||
// destination.
|
||||
func Decode(dst *SubNetworkID, src string) error {
|
||||
// Return error if ID string is too long.
|
||||
if len(src) > MaxStringSize {
|
||||
return ErrIDStrSize
|
||||
}
|
||||
|
||||
// Hex decoder expects the ID to be a multiple of two. When not, pad
|
||||
// with a leading zero.
|
||||
var srcBytes []byte
|
||||
if len(src)%2 == 0 {
|
||||
srcBytes = []byte(src)
|
||||
} else {
|
||||
srcBytes = make([]byte, 1+len(src))
|
||||
srcBytes[0] = '0'
|
||||
copy(srcBytes[1:], src)
|
||||
}
|
||||
|
||||
// Hex decode the source bytes to a temporary destination.
|
||||
var reversedHash SubNetworkID
|
||||
_, err := hex.Decode(reversedHash[IDLength-hex.DecodedLen(len(srcBytes)):], srcBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Reverse copy from the temporary hash to destination. Because the
|
||||
// temporary was zeroed, the written result will be correctly padded.
|
||||
for i, b := range reversedHash[:IDLength/2] {
|
||||
dst[i], dst[IDLength-1-i] = reversedHash[IDLength-1-i], b
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToBig converts a SubNetworkID into a big.Int that can be used to
|
||||
// perform math comparisons.
|
||||
func ToBig(id *SubNetworkID) *big.Int {
|
||||
// A Hash is in little-endian, but the big package wants the bytes in
|
||||
// big-endian, so reverse them.
|
||||
buf := *id
|
||||
blen := len(buf)
|
||||
for i := 0; i < blen/2; i++ {
|
||||
buf[i], buf[blen-1-i] = buf[blen-1-i], buf[i]
|
||||
}
|
||||
|
||||
return new(big.Int).SetBytes(buf[:])
|
||||
}
|
||||
|
||||
// Cmp compares id and target and returns:
|
||||
//
|
||||
// -1 if id < target
|
||||
// 0 if id == target
|
||||
// +1 if id > target
|
||||
//
|
||||
func (id *SubNetworkID) Cmp(target *SubNetworkID) int {
|
||||
return ToBig(id).Cmp(ToBig(target))
|
||||
}
|
||||
|
||||
// Less returns true iff id a is less than id b
|
||||
func Less(a *SubNetworkID, b *SubNetworkID) bool {
|
||||
return a.Cmp(b) < 0
|
||||
}
|
||||
|
||||
// JoinIDsStrings joins all the stringified IDs separated by a separator
|
||||
func JoinIDsStrings(ids []SubNetworkID, separator string) string {
|
||||
return strings.Join(Strings(ids), separator)
|
||||
}
|
||||
|
||||
// Sort sorts a slice of ids
|
||||
func Sort(ids []SubNetworkID) {
|
||||
sort.Slice(ids, func(i, j int) bool {
|
||||
return Less(&ids[i], &ids[j])
|
||||
})
|
||||
}
|
@ -35,7 +35,7 @@ func TestTx(t *testing.T) {
|
||||
}
|
||||
|
||||
// Hash for block 100,000 transaction 0.
|
||||
wantHashStr := "4f2a5f1e00034ed3222e0e7fae8485ad3154d40b21b1c1b64ec74ce389a1bb1d"
|
||||
wantHashStr := "171090dd8ab478a2c4499858abd5d9b10e173b659bab5d5acca68c7dcb4c519e"
|
||||
wantHash, err := daghash.NewHashFromStr(wantHashStr)
|
||||
if err != nil {
|
||||
t.Errorf("NewHashFromStr: %v", err)
|
||||
|
2
util/txsort/testdata/bip69-1.hex
vendored
2
util/txsort/testdata/bip69-1.hex
vendored
File diff suppressed because one or more lines are too long
2
util/txsort/testdata/bip69-2.hex
vendored
2
util/txsort/testdata/bip69-2.hex
vendored
@ -1 +1 @@
|
||||
010000000255605DC6F5C3DC148B6DA58442B0B2CD422BE385EAB2EBEA4119EE9C268D28350000000049483045022100AA46504BAA86DF8A33B1192B1B9367B4D729DC41E389F2C04F3E5C7F0559AAE702205E82253A54BF5C4F65B7428551554B2045167D6D206DFE6A2E198127D3F7DF1501FFFFFFFFFFFFFFFF55605DC6F5C3DC148B6DA58442B0B2CD422BE385EAB2EBEA4119EE9C268D2835010000004847304402202329484C35FA9D6BB32A55A70C0982F606CE0E3634B69006138683BCD12CBB6602200C28FEB1E2555C3210F1DDDB299738B4FF8BBE9667B68CB8764B5AC17B7ADF0001FFFFFFFFFFFFFFFF0200E1F505000000004341046A0765B5865641CE08DD39690AADE26DFBF5511430CA428A3089261361CEF170E3929A68AEE3D8D4848B0C5111B0A37B82B86AD559FD2A745B44D8E8D9DFDC0CAC00180D8F000000004341044A656F065871A353F216CA26CEF8DDE2F03E8C16202D2E8AD769F02032CB86A5EB5E56842E92E19141D60A01928F8DD2C875A390F67C1F6C94CFC617C0EA45AFAC00000000000000000100000000000000
|
||||
010000000255605DC6F5C3DC148B6DA58442B0B2CD422BE385EAB2EBEA4119EE9C268D28350000000049483045022100AA46504BAA86DF8A33B1192B1B9367B4D729DC41E389F2C04F3E5C7F0559AAE702205E82253A54BF5C4F65B7428551554B2045167D6D206DFE6A2E198127D3F7DF1501FFFFFFFFFFFFFFFF55605DC6F5C3DC148B6DA58442B0B2CD422BE385EAB2EBEA4119EE9C268D2835010000004847304402202329484C35FA9D6BB32A55A70C0982F606CE0E3634B69006138683BCD12CBB6602200C28FEB1E2555C3210F1DDDB299738B4FF8BBE9667B68CB8764B5AC17B7ADF0001FFFFFFFFFFFFFFFF0200E1F505000000004341046A0765B5865641CE08DD39690AADE26DFBF5511430CA428A3089261361CEF170E3929A68AEE3D8D4848B0C5111B0A37B82B86AD559FD2A745B44D8E8D9DFDC0CAC00180D8F000000004341044A656F065871A353F216CA26CEF8DDE2F03E8C16202D2E8AD769F02032CB86A5EB5E56842E92E19141D60A01928F8DD2C875A390F67C1F6C94CFC617C0EA45AFAC00000000000000000100000000000000000000000000000000000000
|
2
util/txsort/testdata/bip69-3.hex
vendored
2
util/txsort/testdata/bip69-3.hex
vendored
@ -1 +1 @@
|
||||
0100000001d992e5a888a86d4c7a6a69167a4728ee69497509740fc5f456a24528c340219a000000008b483045022100f0519bdc9282ff476da1323b8ef7ffe33f495c1a8d52cc522b437022d83f6a230220159b61d197fbae01b4a66622a23bc3f1def65d5fa24efd5c26fa872f3a246b8e014104839f9023296a1fabb133140128ca2709f6818c7d099491690bd8ac0fd55279def6a2ceb6ab7b5e4a71889b6e739f09509565eec789e86886f6f936fa42097adeffffffffffffffff02000fe208010000001976a914948c765a6914d43f2a7ac177da2c2f6b52de3d7c88ac00e32321000000001976a9140c34f4e29ab5a615d5ea28d4817f12b137d62ed588ac00000000000000000100000000000000
|
||||
0100000001d992e5a888a86d4c7a6a69167a4728ee69497509740fc5f456a24528c340219a000000008b483045022100f0519bdc9282ff476da1323b8ef7ffe33f495c1a8d52cc522b437022d83f6a230220159b61d197fbae01b4a66622a23bc3f1def65d5fa24efd5c26fa872f3a246b8e014104839f9023296a1fabb133140128ca2709f6818c7d099491690bd8ac0fd55279def6a2ceb6ab7b5e4a71889b6e739f09509565eec789e86886f6f936fa42097adeffffffffffffffff02000fe208010000001976a914948c765a6914d43f2a7ac177da2c2f6b52de3d7c88ac00e32321000000001976a9140c34f4e29ab5a615d5ea28d4817f12b137d62ed588ac00000000000000000100000000000000000000000000000000000000
|
2
util/txsort/testdata/bip69-4.hex
vendored
2
util/txsort/testdata/bip69-4.hex
vendored
@ -1 +1 @@
|
||||
01000000059daf0abe7a92618546a9dbcfd65869b6178c66ec21ccfda878c1175979cfd9ef000000004a493046022100c2f7f25be5de6ce88ac3c1a519514379e91f39b31ddff279a3db0b1a229b708b022100b29efbdbd9837cc6a6c7318aa4900ed7e4d65662c34d1622a2035a3a5534a99a01ffffffffffffffffd516330ebdf075948da56db13d22632a4fb941122df2884397dda45d451acefb0000000048473044022051243debe6d4f2b433bee0cee78c5c4073ead0e3bde54296dbed6176e128659c022044417bfe16f44eb7b6eb0cdf077b9ce972a332e15395c09ca5e4f602958d266101ffffffffffffffffe1f5aa33961227b3c344e57179417ce01b7ccd421117fe2336289b70489883f900000000484730440220593252bb992ce3c85baf28d6e3aa32065816271d2c822398fe7ee28a856bc943022066d429dd5025d3c86fd8fd8a58e183a844bd94aa312cefe00388f57c85b0ca3201ffffffffffffffffe207e83718129505e6a7484831442f668164ae659fddb82e9e5421a081fb90d50000000049483045022067cf27eb733e5bcae412a586b25a74417c237161a084167c2a0b439abfebdcb2022100efcc6baa6824b4c5205aa967e0b76d31abf89e738d4b6b014e788c9a8cccaf0c01ffffffffffffffffe23b8d9d80a9e9d977fab3c94dbe37befee63822443c3ec5ae5a713ede66c3940000000049483045022020f2eb35036666b1debe0d1d2e77a36d5d9c4e96c1dba23f5100f193dbf524790221008ce79bc1321fb4357c6daee818038d41544749127751726e46b2b320c8b565a201ffffffffffffffff0200ba1dd2050000001976a914366a27645806e817a6cd40bc869bdad92fe5509188ac40420f00000000001976a914ee8bd501094a7d5ca318da2506de35e1cb025ddc88ac00000000000000000100000000000000
|
||||
01000000059daf0abe7a92618546a9dbcfd65869b6178c66ec21ccfda878c1175979cfd9ef000000004a493046022100c2f7f25be5de6ce88ac3c1a519514379e91f39b31ddff279a3db0b1a229b708b022100b29efbdbd9837cc6a6c7318aa4900ed7e4d65662c34d1622a2035a3a5534a99a01ffffffffffffffffd516330ebdf075948da56db13d22632a4fb941122df2884397dda45d451acefb0000000048473044022051243debe6d4f2b433bee0cee78c5c4073ead0e3bde54296dbed6176e128659c022044417bfe16f44eb7b6eb0cdf077b9ce972a332e15395c09ca5e4f602958d266101ffffffffffffffffe1f5aa33961227b3c344e57179417ce01b7ccd421117fe2336289b70489883f900000000484730440220593252bb992ce3c85baf28d6e3aa32065816271d2c822398fe7ee28a856bc943022066d429dd5025d3c86fd8fd8a58e183a844bd94aa312cefe00388f57c85b0ca3201ffffffffffffffffe207e83718129505e6a7484831442f668164ae659fddb82e9e5421a081fb90d50000000049483045022067cf27eb733e5bcae412a586b25a74417c237161a084167c2a0b439abfebdcb2022100efcc6baa6824b4c5205aa967e0b76d31abf89e738d4b6b014e788c9a8cccaf0c01ffffffffffffffffe23b8d9d80a9e9d977fab3c94dbe37befee63822443c3ec5ae5a713ede66c3940000000049483045022020f2eb35036666b1debe0d1d2e77a36d5d9c4e96c1dba23f5100f193dbf524790221008ce79bc1321fb4357c6daee818038d41544749127751726e46b2b320c8b565a201ffffffffffffffff0200ba1dd2050000001976a914366a27645806e817a6cd40bc869bdad92fe5509188ac40420f00000000001976a914ee8bd501094a7d5ca318da2506de35e1cb025ddc88ac00000000000000000100000000000000000000000000000000000000
|
2
util/txsort/testdata/bip69-5.hex
vendored
2
util/txsort/testdata/bip69-5.hex
vendored
@ -1 +1 @@
|
||||
01000000011f636d0003f673b3aeea4971daef16b8eed784cf6e8019a5ae7da4985fbb06e5000000008a47304402205103941e2b11e746dfa817888d422f6e7f4d16dbbfb8ffa61d15ffb924a84b8802202fe861b0f23f17139d15a3374bfc6c7196d371f3d1a324e31cc0aadbba87e53c0141049e7e1b251a7e26cae9ee7553b278ef58ef3c28b4b20134d51b747d9b18b0a19b94b66cef320e2549dec0ea3d725cb4c742f368928b1fb74b4603e24a1e262c80ffffffffffffffff0240420f00000000001976a914bcfa0e27218a7c97257b351b03a9eac95c25a23988ac40420f00000000001976a9140c6a68f20bafc678164d171ee4f077adfa9b091688ac00000000000000000100000000000000
|
||||
01000000011f636d0003f673b3aeea4971daef16b8eed784cf6e8019a5ae7da4985fbb06e5000000008a47304402205103941e2b11e746dfa817888d422f6e7f4d16dbbfb8ffa61d15ffb924a84b8802202fe861b0f23f17139d15a3374bfc6c7196d371f3d1a324e31cc0aadbba87e53c0141049e7e1b251a7e26cae9ee7553b278ef58ef3c28b4b20134d51b747d9b18b0a19b94b66cef320e2549dec0ea3d725cb4c742f368928b1fb74b4603e24a1e262c80ffffffffffffffff0240420f00000000001976a914bcfa0e27218a7c97257b351b03a9eac95c25a23988ac40420f00000000001976a9140c6a68f20bafc678164d171ee4f077adfa9b091688ac00000000000000000100000000000000000000000000000000000000
|
@ -28,36 +28,36 @@ func TestSort(t *testing.T) {
|
||||
name: "first test case from BIP 69 - sorts inputs only, based on hash",
|
||||
hexFile: "bip69-1.hex",
|
||||
isSorted: false,
|
||||
unsortedHash: "55721464fe5511e70792da14d7c4f20f6e81d5e7197919e536d0598796daaef3",
|
||||
sortedHash: "573054025c067ab92e3e8b66cf25d16dbb8ab4ff9e9ef9ece79d2aee83f06785",
|
||||
unsortedHash: "6b178242e9b6c1d448e2fa7d52fb7ec8dcea289c7852f1184880aabaef4da412",
|
||||
sortedHash: "ab07dbc63d1376cfb4f122722748a9f1487adb66fbbb682c593da602723f22c3",
|
||||
},
|
||||
{
|
||||
name: "second test case from BIP 69 - already sorted",
|
||||
hexFile: "bip69-2.hex",
|
||||
isSorted: true,
|
||||
unsortedHash: "b9ce1181a9f94375000c9a49fc097a9abe9eb85a0f2e6792e1ec0ac24f72172b",
|
||||
sortedHash: "b9ce1181a9f94375000c9a49fc097a9abe9eb85a0f2e6792e1ec0ac24f72172b",
|
||||
unsortedHash: "ef51200d830bf2bc77b50e3b92f878d82f6f8d29d7e0d031782f24e2af023601",
|
||||
sortedHash: "ef51200d830bf2bc77b50e3b92f878d82f6f8d29d7e0d031782f24e2af023601",
|
||||
},
|
||||
{
|
||||
name: "block 100001 tx[1] - sorts outputs only, based on amount",
|
||||
hexFile: "bip69-3.hex",
|
||||
isSorted: false,
|
||||
unsortedHash: "a1fd1029514fb555ecaa6126849d66a19c4239b2a77bdace6f6ef7db3cc23f30",
|
||||
sortedHash: "4234b089ff83ec954b76e8b56449c095718124ebedd4cf8642d49f02ae55ade2",
|
||||
unsortedHash: "36e32ff592786843a4b80dc1029129530e93c885a1cbeb9ef2bed309b336b92e",
|
||||
sortedHash: "f971eb5dd57cc6848c0b903440c175a2fe0d93004099b1582e201de8d60ef6dc",
|
||||
},
|
||||
{
|
||||
name: "block 100001 tx[2] - sorts both inputs and outputs",
|
||||
hexFile: "bip69-4.hex",
|
||||
isSorted: false,
|
||||
unsortedHash: "d2eb3b56e3be83886dc5ee5789c332ba77f0f3f53abe98d306c1b2e9c25045a2",
|
||||
sortedHash: "280567fe8d4cda60aa1d1b6ca87dd5944d761e8dee72a704af71365696988cda",
|
||||
unsortedHash: "355b28a1b5e05c937755182169cbb6cfd58c9c50122ce430efb83c650c9aadef",
|
||||
sortedHash: "4f0f023e7fc32a893fa156ca3001d1be4f1ff86f6d7b69d36f76fa0f427e765a",
|
||||
},
|
||||
{
|
||||
name: "block 100998 tx[6] - sorts outputs only, based on output script",
|
||||
hexFile: "bip69-5.hex",
|
||||
isSorted: false,
|
||||
unsortedHash: "5c83c1b03b7a1c80a44686323ea17d5bc60a976efb5a3de116cb99cac6ec2557",
|
||||
sortedHash: "23c0abbbd17ca34980c9330e10b2c9230d72cec5aba38306ea676bbfa789a125",
|
||||
unsortedHash: "f1d10b059664f8711d7a0960ce7763a89a89c697a74b8b5db4dbf850c0973fd6",
|
||||
sortedHash: "76405dc7da88f622481b5e9d6894a45a45f7c376d1f95a390b8a494b7767ff71",
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -91,11 +91,11 @@ func TestMessage(t *testing.T) {
|
||||
{msgGetAddr, msgGetAddr, pver, MainNet, 24},
|
||||
{msgAddr, msgAddr, pver, MainNet, 25},
|
||||
{msgGetBlocks, msgGetBlocks, pver, MainNet, 61},
|
||||
{msgBlock, msgBlock, pver, MainNet, 296},
|
||||
{msgBlock, msgBlock, pver, MainNet, 308},
|
||||
{msgInv, msgInv, pver, MainNet, 25},
|
||||
{msgGetData, msgGetData, pver, MainNet, 25},
|
||||
{msgNotFound, msgNotFound, pver, MainNet, 25},
|
||||
{msgTx, msgTx, pver, MainNet, 46},
|
||||
{msgTx, msgTx, pver, MainNet, 58},
|
||||
{msgPing, msgPing, pver, MainNet, 32},
|
||||
{msgPong, msgPong, pver, MainNet, 32},
|
||||
{msgGetHeaders, msgGetHeaders, pver, MainNet, 61},
|
||||
|
@ -72,7 +72,7 @@ func TestBlock(t *testing.T) {
|
||||
// hashes from a block accurately.
|
||||
func TestBlockTxHashes(t *testing.T) {
|
||||
// Block 1, transaction 1 hash.
|
||||
hashStr := "603ea191aecb5809c78790a0bd58293086c1b19118e7251a38680dd9e1dc3b32"
|
||||
hashStr := "f8f148865a0ecb895a2b8fffd37245b3d4f5e01213bdaaa38a52b74e2f3289b4"
|
||||
wantHash, err := daghash.NewHashFromStr(hashStr)
|
||||
if err != nil {
|
||||
t.Errorf("NewHashFromStr: %v", err)
|
||||
@ -583,10 +583,12 @@ var blockOneBytes = []byte{
|
||||
0xee, // 65-byte uncompressed public key
|
||||
0xac, // OP_CHECKSIG
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Subnetwork ID
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, // Subnetwork ID
|
||||
}
|
||||
|
||||
// Transaction location information for block one transactions.
|
||||
var blockOneTxLocs = []TxLoc{
|
||||
{TxStart: 122, TxLen: 150},
|
||||
{TxStart: 122, TxLen: 162},
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/daglabs/btcd/dagconfig/daghash"
|
||||
"github.com/daglabs/btcd/util/subnetworkid"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -95,23 +96,17 @@ const (
|
||||
// peers. Thus, the peak usage of the free list is 12,500 * 512 =
|
||||
// 6,400,000 bytes.
|
||||
freeListMaxItems = 12500
|
||||
)
|
||||
|
||||
var (
|
||||
// SubNetworkSupportsAll is the sub-network id that is used to signal to peers that you support all sub-networks
|
||||
SubNetworkSupportsAll = 0
|
||||
SubNetworkSupportsAll = subnetworkid.SubNetworkID{}
|
||||
|
||||
// SubNetworkDAGCoin is the default sub-network which is used for transactions without related payload data
|
||||
SubNetworkDAGCoin = 1
|
||||
SubNetworkDAGCoin = subnetworkid.SubNetworkID{1}
|
||||
|
||||
// SubNetworkRegistry is the sub-network which is used for adding new sub networks to the registry
|
||||
SubNetworkRegistry = 2
|
||||
|
||||
// SubNetworkReservedFirst and SubnetworkReservedLast mark the range of sub-networks that are reserved for future use
|
||||
// and are currently un-assigned for anything
|
||||
// SubNetworkReservedFirst is the first reserved sub-network
|
||||
SubNetworkReservedFirst = 3
|
||||
|
||||
// SubNetworkUnreservedFirst is the first unreserved sub-network
|
||||
SubNetworkUnreservedFirst = 256
|
||||
SubNetworkRegistry = subnetworkid.SubNetworkID{2}
|
||||
)
|
||||
|
||||
// scriptFreeList defines a free list of byte slices (up to the maximum number
|
||||
@ -264,7 +259,7 @@ type MsgTx struct {
|
||||
TxIn []*TxIn
|
||||
TxOut []*TxOut
|
||||
LockTime uint64
|
||||
SubNetworkID uint64
|
||||
SubNetworkID subnetworkid.SubNetworkID
|
||||
Gas uint64
|
||||
Payload []byte
|
||||
}
|
||||
@ -463,7 +458,7 @@ func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32) error {
|
||||
return err
|
||||
}
|
||||
|
||||
msg.SubNetworkID, err = binarySerializer.Uint64(r, littleEndian)
|
||||
_, err = io.ReadFull(r, msg.SubNetworkID[:])
|
||||
if err != nil {
|
||||
returnScriptBuffers()
|
||||
return err
|
||||
@ -613,7 +608,7 @@ func (msg *MsgTx) BtcEncode(w io.Writer, pver uint32) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = binarySerializer.PutUint64(w, littleEndian, msg.SubNetworkID)
|
||||
_, err = w.Write(msg.SubNetworkID[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -633,7 +628,10 @@ func (msg *MsgTx) BtcEncode(w io.Writer, pver uint32) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w.Write(msg.Payload)
|
||||
_, err := w.Write(msg.Payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if msg.Payload != nil {
|
||||
str := fmt.Sprintf("Transactions from subnetwork %v should have <nil> payload", msg.SubNetworkID)
|
||||
return messageError("MsgTx.BtcEncode", str)
|
||||
@ -665,10 +663,10 @@ func (msg *MsgTx) Serialize(w io.Writer) error {
|
||||
// SerializeSize returns the number of bytes it would take to serialize the
|
||||
// the transaction.
|
||||
func (msg *MsgTx) SerializeSize() int {
|
||||
// Version 4 bytes + LockTime 8 bytes + Subnetwork ID 8
|
||||
// Version 4 bytes + LockTime 8 bytes + Subnetwork ID 20
|
||||
// bytes + Serialized varint size for the number of transaction
|
||||
// inputs and outputs.
|
||||
n := 20 + VarIntSerializeSize(uint64(len(msg.TxIn))) +
|
||||
n := 32 + VarIntSerializeSize(uint64(len(msg.TxIn))) +
|
||||
VarIntSerializeSize(uint64(len(msg.TxOut)))
|
||||
|
||||
if msg.SubNetworkID != SubNetworkDAGCoin {
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/daglabs/btcd/dagconfig/daghash"
|
||||
"github.com/daglabs/btcd/util/subnetworkid"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
@ -130,7 +131,7 @@ func TestTx(t *testing.T) {
|
||||
// TestTxHash tests the ability to generate the hash of a transaction accurately.
|
||||
func TestTxHash(t *testing.T) {
|
||||
// Hash of first transaction from block 113875.
|
||||
hashStr := "bc103ee9c89185146ba4e3eb9e936d46acd312cd8d2c5865fa4b0c02e67d0959"
|
||||
hashStr := "2d0dd1e05410fe76afbd90f577f615d603ca00b2fa53f963e6375ce742343faa"
|
||||
wantHash, err := daghash.NewHashFromStr(hashStr)
|
||||
if err != nil {
|
||||
t.Errorf("NewHashFromStr: %v", err)
|
||||
@ -186,7 +187,9 @@ func TestTxWire(t *testing.T) {
|
||||
0x00, // Varint for number of input transactions
|
||||
0x00, // Varint for number of output transactions
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Sub Network ID
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, // Sub Network ID
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
@ -198,7 +201,8 @@ func TestTxWire(t *testing.T) {
|
||||
// Latest protocol version with no transactions.
|
||||
{
|
||||
noTx,
|
||||
noTx, noTxEncoded,
|
||||
noTx,
|
||||
noTxEncoded,
|
||||
ProtocolVersion,
|
||||
},
|
||||
|
||||
@ -380,7 +384,9 @@ func TestTxSerialize(t *testing.T) {
|
||||
0x00, // Varint for number of input transactions
|
||||
0x00, // Varint for number of output transactions
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Sub Network ID
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, // Sub Network ID
|
||||
}
|
||||
|
||||
registryTx := newRegistryMsgTx(1, 16)
|
||||
@ -389,14 +395,16 @@ func TestTxSerialize(t *testing.T) {
|
||||
0x00, // Varint for number of input transactions
|
||||
0x00, // Varint for number of output transactions
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Sub Network ID
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, // Sub Network ID
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Gas
|
||||
0x08, // Payload length varint
|
||||
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Payload / Gas limit
|
||||
}
|
||||
|
||||
subNetworkTx := NewMsgTx(1)
|
||||
subNetworkTx.SubNetworkID = 0xff
|
||||
subNetworkTx.SubNetworkID = subnetworkid.SubNetworkID{0xff}
|
||||
subNetworkTx.Gas = 5
|
||||
subNetworkTx.Payload = []byte{0, 1, 2}
|
||||
|
||||
@ -405,7 +413,9 @@ func TestTxSerialize(t *testing.T) {
|
||||
0x00, // Varint for number of input transactions
|
||||
0x00, // Varint for number of output transactions
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Sub Network ID
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, // Sub Network ID
|
||||
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Gas
|
||||
0x03, // Payload length varint
|
||||
0x00, 0x01, 0x02, // Payload
|
||||
@ -597,7 +607,9 @@ func TestTxSerializeErrors(t *testing.T) {
|
||||
0x00, // Varint for number of input transactions
|
||||
0x00, // Varint for number of output transactions
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Sub Network ID
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, // Sub Network ID
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Gas
|
||||
0x08, // Payload length varint
|
||||
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Payload / Gas limit
|
||||
@ -607,7 +619,7 @@ func TestTxSerializeErrors(t *testing.T) {
|
||||
var tx MsgTx
|
||||
err = tx.Deserialize(r)
|
||||
|
||||
str = fmt.Sprintf("%v is a reserved sub network and cannot be used as part of a transaction", 0)
|
||||
str = fmt.Sprintf("%v is a reserved sub network and cannot be used as part of a transaction", SubNetworkSupportsAll)
|
||||
expectedErr = messageError("MsgTx.BtcDecode", str)
|
||||
if err == nil || err.Error() != expectedErr.Error() {
|
||||
t.Errorf("TestTxSerializeErrors: expected error %v but got %v", expectedErr, err)
|
||||
@ -618,7 +630,9 @@ func TestTxSerializeErrors(t *testing.T) {
|
||||
0x00, // Varint for number of input transactions
|
||||
0x00, // Varint for number of output transactions
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Sub Network ID
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, // Sub Network ID
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Gas
|
||||
0x08, // Payload length varint
|
||||
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Payload / Gas limit
|
||||
@ -638,7 +652,9 @@ func TestTxSerializeErrors(t *testing.T) {
|
||||
0x00, // Varint for number of input transactions
|
||||
0x00, // Varint for number of output transactions
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Sub Network ID
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, // Sub Network ID
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Gas
|
||||
0x03, // Payload length varint
|
||||
0x01, 0x02, 0x03, // Payload / Gas limit
|
||||
@ -762,10 +778,10 @@ func TestTxSerializeSize(t *testing.T) {
|
||||
size int // Expected serialized size
|
||||
}{
|
||||
// No inputs or outpus.
|
||||
{noTx, 22},
|
||||
{noTx, 34},
|
||||
|
||||
// Transcaction with an input and an output.
|
||||
{multiTx, 226},
|
||||
{multiTx, 238},
|
||||
}
|
||||
|
||||
t.Logf("Running %d tests", len(tests))
|
||||
@ -942,7 +958,9 @@ var multiTxEncoded = []byte{
|
||||
0xa6, // 65-byte signature
|
||||
0xac, // OP_CHECKSIG
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Lock time
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Sub Network ID
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, // Sub Network ID
|
||||
}
|
||||
|
||||
// multiTxPkScriptLocs is the location information for the public key scripts
|
||||
|
Loading…
x
Reference in New Issue
Block a user