mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-09-13 21:10:12 +00:00

* Add StagingArea struct * Implemented staging areas in blockStore * Move blockStagingShard to separate folder * Apply staging shard to acceptanceDataStore * Update blockHeaderStore with StagingArea * Add StagingArea to BlockRelationStore * Add StagingArea to blockStatusStore * Add StagingArea to consensusStateStore * Add StagingArea to daaBlocksStore * Add StagingArea to finalityStore * Add StagingArea to ghostdagDataStore * Add StagingArea to headersSelectedChainStore and headersSelectedTipStore * Add StagingArea to multisetStore * Add StagingArea to pruningStore * Add StagingArea to reachabilityDataStore * Add StagingArea to utxoDiffStore * Fix forgotten compilation error * Update reachability manager and some more things with StagingArea * Add StagingArea to dagTopologyManager, and some more * Add StagingArea to GHOSTDAGManager, and some more * Add StagingArea to difficultyManager, and some more * Add StagingArea to dagTraversalManager, and some more * Add StagingArea to headerTipsManager, and some more * Add StagingArea to constnsusStateManager, pastMedianTimeManager * Add StagingArea to transactionValidator * Add StagingArea to finalityManager * Add StagingArea to mergeDepthManager * Add StagingArea to pruningManager * Add StagingArea to rest of ValidateAndInsertBlock * Add StagingArea to blockValidator * Add StagingArea to coinbaseManager * Add StagingArea to syncManager * Add StagingArea to blockBuilder * Update consensus with StagingArea * Add StagingArea to ghostdag2 * Fix remaining compilation errors * Update names of stagingShards * Fix forgotten stagingArea passing * Mark stagingShard.isCommited = true once commited * Move isStaged to stagingShard, so that it's available without going through store * Make blockHeaderStore count be avilable from stagingShard * Fix remaining forgotten stagingArea passing * commitAllChanges should call dbTx.Commit in the end * Fix all tests tests in blockValidator * Fix all tests in consensusStateManager and some more * Fix all tests in pruningManager * Add many missing stagingAreas in tests * Fix many tests * Fix most of all other tests * Fix ghostdag_test.go * Add comment to StagingArea * Make list of StagingShards an array * Add comment to StagingShardID * Make sure all staging shards are pointer-receiver * Undo bucket rename in block_store * Typo: isCommited -> isCommitted * Add comment explaining why stagingArea.shards is an array
62 lines
3.3 KiB
Go
62 lines
3.3 KiB
Go
package coinbasemanager
|
|
|
|
import (
|
|
"encoding/binary"
|
|
|
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
|
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
const uint64Len = 8
|
|
const uint16Len = 2
|
|
const lengthOfscriptPubKeyLength = 1
|
|
const lengthOfVersionScriptPubKey = uint16Len
|
|
|
|
// serializeCoinbasePayload builds the coinbase payload based on the provided scriptPubKey and extra data.
|
|
func (c *coinbaseManager) serializeCoinbasePayload(blueScore uint64, coinbaseData *externalapi.DomainCoinbaseData) ([]byte, error) {
|
|
scriptLengthOfScriptPubKey := len(coinbaseData.ScriptPublicKey.Script)
|
|
if scriptLengthOfScriptPubKey > int(c.coinbasePayloadScriptPublicKeyMaxLength) {
|
|
return nil, errors.Wrapf(ruleerrors.ErrBadCoinbasePayloadLen, "coinbase's payload script public key is "+
|
|
"longer than the max allowed length of %d", c.coinbasePayloadScriptPublicKeyMaxLength)
|
|
}
|
|
|
|
payload := make([]byte, uint64Len+lengthOfVersionScriptPubKey+lengthOfscriptPubKeyLength+scriptLengthOfScriptPubKey+len(coinbaseData.ExtraData))
|
|
binary.LittleEndian.PutUint64(payload[:uint64Len], blueScore)
|
|
|
|
payload[uint64Len] = uint8(coinbaseData.ScriptPublicKey.Version)
|
|
payload[uint64Len+lengthOfVersionScriptPubKey] = uint8(len(coinbaseData.ScriptPublicKey.Script))
|
|
copy(payload[uint64Len+lengthOfVersionScriptPubKey+lengthOfscriptPubKeyLength:], coinbaseData.ScriptPublicKey.Script)
|
|
copy(payload[uint64Len+lengthOfVersionScriptPubKey+lengthOfscriptPubKeyLength+scriptLengthOfScriptPubKey:], coinbaseData.ExtraData)
|
|
return payload, nil
|
|
}
|
|
|
|
// ExtractCoinbaseDataAndBlueScore deserializes the coinbase payload to its component (scriptPubKey and extra data).
|
|
func (c *coinbaseManager) ExtractCoinbaseDataAndBlueScore(coinbaseTx *externalapi.DomainTransaction) (blueScore uint64, coinbaseData *externalapi.DomainCoinbaseData, err error) {
|
|
|
|
minLength := uint64Len + lengthOfVersionScriptPubKey + lengthOfscriptPubKeyLength
|
|
if len(coinbaseTx.Payload) < minLength {
|
|
return 0, nil, errors.Wrapf(ruleerrors.ErrBadCoinbasePayloadLen,
|
|
"coinbase payload is less than the minimum length of %d", minLength)
|
|
}
|
|
|
|
blueScore = binary.LittleEndian.Uint64(coinbaseTx.Payload[:uint64Len])
|
|
scriptPubKeyVersion := uint16(coinbaseTx.Payload[uint64Len])
|
|
scriptPubKeyScriptLength := coinbaseTx.Payload[uint64Len+lengthOfVersionScriptPubKey]
|
|
|
|
if scriptPubKeyScriptLength > c.coinbasePayloadScriptPublicKeyMaxLength {
|
|
return 0, nil, errors.Wrapf(ruleerrors.ErrBadCoinbasePayloadLen, "coinbase's payload script public key is "+
|
|
"longer than the max allowed length of %d", c.coinbasePayloadScriptPublicKeyMaxLength)
|
|
}
|
|
|
|
if len(coinbaseTx.Payload) < minLength+int(scriptPubKeyScriptLength) {
|
|
return 0, nil, errors.Wrapf(ruleerrors.ErrBadCoinbasePayloadLen,
|
|
"coinbase payload doesn't have enough bytes to contain a script public key of %d bytes", scriptPubKeyScriptLength)
|
|
}
|
|
scriptPubKeyScript := coinbaseTx.Payload[uint64Len+lengthOfVersionScriptPubKey+lengthOfscriptPubKeyLength : uint64Len+lengthOfVersionScriptPubKey+lengthOfscriptPubKeyLength+scriptPubKeyScriptLength]
|
|
return blueScore, &externalapi.DomainCoinbaseData{
|
|
ScriptPublicKey: &externalapi.ScriptPublicKey{Script: scriptPubKeyScript, Version: scriptPubKeyVersion},
|
|
ExtraData: coinbaseTx.Payload[uint64Len+lengthOfVersionScriptPubKey+lengthOfscriptPubKeyLength+scriptPubKeyScriptLength:],
|
|
}, nil
|
|
}
|