refactor(consensus): expand fork-state naming
Co-Authored-By: Charon <charon@lethean.io>
This commit is contained in:
parent
d5070cce15
commit
330ee2a146
4 changed files with 43 additions and 43 deletions
|
|
@ -84,10 +84,10 @@ func ValidateMinerTx(tx *types.Transaction, height uint64, forks []config.HardFo
|
||||||
tx.Version, height, expectedVersion), ErrMinerTxVersion)
|
tx.Version, height, expectedVersion), ErrMinerTxVersion)
|
||||||
}
|
}
|
||||||
if tx.Version >= types.VersionPostHF5 {
|
if tx.Version >= types.VersionPostHF5 {
|
||||||
currentFork := config.VersionAtHeight(forks, height)
|
activeHardForkVersion := config.VersionAtHeight(forks, height)
|
||||||
if tx.HardforkID != currentFork {
|
if tx.HardforkID != activeHardForkVersion {
|
||||||
return coreerr.E("ValidateMinerTx", fmt.Sprintf("hardfork id %d does not match active fork %d at height %d",
|
return coreerr.E("ValidateMinerTx", fmt.Sprintf("hardfork id %d does not match active fork %d at height %d",
|
||||||
tx.HardforkID, currentFork, height), ErrMinerTxVersion)
|
tx.HardforkID, activeHardForkVersion, height), ErrMinerTxVersion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,8 +113,8 @@ func ValidateMinerTx(tx *types.Transaction, height uint64, forks []config.HardFo
|
||||||
case types.TxInputToKey:
|
case types.TxInputToKey:
|
||||||
// Pre-HF4 PoS.
|
// Pre-HF4 PoS.
|
||||||
case types.TxInputZC:
|
case types.TxInputZC:
|
||||||
hf4Active := config.IsHardForkActive(forks, config.HF4Zarcanum, height)
|
hardForkFourActive := config.IsHardForkActive(forks, config.HF4Zarcanum, height)
|
||||||
if !hf4Active {
|
if !hardForkFourActive {
|
||||||
return coreerr.E("ValidateMinerTx", "invalid PoS stake input type", ErrMinerTxInputs)
|
return coreerr.E("ValidateMinerTx", "invalid PoS stake input type", ErrMinerTxInputs)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
@ -139,8 +139,8 @@ func ValidateBlockReward(minerTx *types.Transaction, height, blockSize, medianSi
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
hf4Active := config.IsHardForkActive(forks, config.HF4Zarcanum, height)
|
hardForkFourActive := config.IsHardForkActive(forks, config.HF4Zarcanum, height)
|
||||||
expected := MinerReward(reward, totalFees, hf4Active)
|
expected := MinerReward(reward, totalFees, hardForkFourActive)
|
||||||
|
|
||||||
// Sum miner tx outputs.
|
// Sum miner tx outputs.
|
||||||
var outputSum uint64
|
var outputSum uint64
|
||||||
|
|
|
||||||
|
|
@ -15,26 +15,26 @@ import (
|
||||||
"dappco.re/go/core/blockchain/wire"
|
"dappco.re/go/core/blockchain/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
type txForkState struct {
|
type transactionForkState struct {
|
||||||
currentFork uint8
|
activeHardForkVersion uint8
|
||||||
hf1Active bool
|
hardForkOneActive bool
|
||||||
hf4Active bool
|
hardForkFourActive bool
|
||||||
hf5Active bool
|
hardForkFiveActive bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTxForkState(forks []config.HardFork, height uint64) txForkState {
|
func newTransactionForkState(forks []config.HardFork, height uint64) transactionForkState {
|
||||||
return txForkState{
|
return transactionForkState{
|
||||||
currentFork: config.VersionAtHeight(forks, height),
|
activeHardForkVersion: config.VersionAtHeight(forks, height),
|
||||||
hf1Active: config.IsHardForkActive(forks, config.HF1, height),
|
hardForkOneActive: config.IsHardForkActive(forks, config.HF1, height),
|
||||||
hf4Active: config.IsHardForkActive(forks, config.HF4Zarcanum, height),
|
hardForkFourActive: config.IsHardForkActive(forks, config.HF4Zarcanum, height),
|
||||||
hf5Active: config.IsHardForkActive(forks, config.HF5, height),
|
hardForkFiveActive: config.IsHardForkActive(forks, config.HF5, height),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateTransaction performs semantic validation on a regular (non-coinbase)
|
// ValidateTransaction performs semantic validation on a regular (non-coinbase)
|
||||||
// transaction. Checks are ordered to match the C++ validate_tx_semantic().
|
// transaction. Checks are ordered to match the C++ validate_tx_semantic().
|
||||||
func ValidateTransaction(tx *types.Transaction, txBlob []byte, forks []config.HardFork, height uint64) error {
|
func ValidateTransaction(tx *types.Transaction, txBlob []byte, forks []config.HardFork, height uint64) error {
|
||||||
state := newTxForkState(forks, height)
|
state := newTransactionForkState(forks, height)
|
||||||
|
|
||||||
// 0. Transaction version.
|
// 0. Transaction version.
|
||||||
if err := checkTxVersion(tx, state, height); err != nil {
|
if err := checkTxVersion(tx, state, height); err != nil {
|
||||||
|
|
@ -65,7 +65,7 @@ func ValidateTransaction(tx *types.Transaction, txBlob []byte, forks []config.Ha
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4a. HF5 asset operation validation inside extra.
|
// 4a. HF5 asset operation validation inside extra.
|
||||||
if err := checkAssetOperations(tx.Extra, state.hf5Active); err != nil {
|
if err := checkAssetOperations(tx.Extra, state.hardForkFiveActive); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,7 +83,7 @@ func ValidateTransaction(tx *types.Transaction, txBlob []byte, forks []config.Ha
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. Balance check (pre-HF4 only — post-HF4 uses commitment proofs).
|
// 7. Balance check (pre-HF4 only — post-HF4 uses commitment proofs).
|
||||||
if !state.hf4Active {
|
if !state.hardForkFourActive {
|
||||||
if _, err := TxFee(tx); err != nil {
|
if _, err := TxFee(tx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -99,12 +99,12 @@ func ValidateTransaction(tx *types.Transaction, txBlob []byte, forks []config.Ha
|
||||||
// HF4 era: regular transactions must use version 2.
|
// HF4 era: regular transactions must use version 2.
|
||||||
// HF5+: transaction version must be exactly version 3 and the embedded
|
// HF5+: transaction version must be exactly version 3 and the embedded
|
||||||
// hardfork_id must match the active hardfork version.
|
// hardfork_id must match the active hardfork version.
|
||||||
func checkTxVersion(tx *types.Transaction, state txForkState, height uint64) error {
|
func checkTxVersion(tx *types.Transaction, state transactionForkState, height uint64) error {
|
||||||
var expectedVersion uint64
|
var expectedVersion uint64
|
||||||
switch {
|
switch {
|
||||||
case state.hf5Active:
|
case state.hardForkFiveActive:
|
||||||
expectedVersion = types.VersionPostHF5
|
expectedVersion = types.VersionPostHF5
|
||||||
case state.hf4Active:
|
case state.hardForkFourActive:
|
||||||
expectedVersion = types.VersionPostHF4
|
expectedVersion = types.VersionPostHF4
|
||||||
default:
|
default:
|
||||||
expectedVersion = types.VersionPreHF4
|
expectedVersion = types.VersionPreHF4
|
||||||
|
|
@ -116,16 +116,16 @@ func checkTxVersion(tx *types.Transaction, state txForkState, height uint64) err
|
||||||
ErrTxVersionInvalid)
|
ErrTxVersionInvalid)
|
||||||
}
|
}
|
||||||
|
|
||||||
if tx.Version >= types.VersionPostHF5 && tx.HardforkID != state.currentFork {
|
if tx.Version >= types.VersionPostHF5 && tx.HardforkID != state.activeHardForkVersion {
|
||||||
return coreerr.E("checkTxVersion",
|
return coreerr.E("checkTxVersion",
|
||||||
fmt.Sprintf("hardfork id %d does not match active fork %d at height %d", tx.HardforkID, state.currentFork, height),
|
fmt.Sprintf("hardfork id %d does not match active fork %d at height %d", tx.HardforkID, state.activeHardForkVersion, height),
|
||||||
ErrTxVersionInvalid)
|
ErrTxVersionInvalid)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkInputTypes(tx *types.Transaction, state txForkState) error {
|
func checkInputTypes(tx *types.Transaction, state transactionForkState) error {
|
||||||
for _, vin := range tx.Vin {
|
for _, vin := range tx.Vin {
|
||||||
switch vin.(type) {
|
switch vin.(type) {
|
||||||
case types.TxInputToKey:
|
case types.TxInputToKey:
|
||||||
|
|
@ -134,11 +134,11 @@ func checkInputTypes(tx *types.Transaction, state txForkState) error {
|
||||||
return coreerr.E("checkInputTypes", "txin_gen in regular transaction", ErrInvalidInputType)
|
return coreerr.E("checkInputTypes", "txin_gen in regular transaction", ErrInvalidInputType)
|
||||||
case types.TxInputHTLC, types.TxInputMultisig:
|
case types.TxInputHTLC, types.TxInputMultisig:
|
||||||
// HTLC and multisig inputs require at least HF1.
|
// HTLC and multisig inputs require at least HF1.
|
||||||
if !state.hf1Active {
|
if !state.hardForkOneActive {
|
||||||
return coreerr.E("checkInputTypes", fmt.Sprintf("tag %d pre-HF1", vin.InputType()), ErrInvalidInputType)
|
return coreerr.E("checkInputTypes", fmt.Sprintf("tag %d pre-HF1", vin.InputType()), ErrInvalidInputType)
|
||||||
}
|
}
|
||||||
case types.TxInputZC:
|
case types.TxInputZC:
|
||||||
if !state.hf4Active {
|
if !state.hardForkFourActive {
|
||||||
return coreerr.E("checkInputTypes", fmt.Sprintf("tag %d pre-HF4", vin.InputType()), ErrInvalidInputType)
|
return coreerr.E("checkInputTypes", fmt.Sprintf("tag %d pre-HF4", vin.InputType()), ErrInvalidInputType)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
@ -148,12 +148,12 @@ func checkInputTypes(tx *types.Transaction, state txForkState) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkOutputs(tx *types.Transaction, state txForkState) error {
|
func checkOutputs(tx *types.Transaction, state transactionForkState) error {
|
||||||
if len(tx.Vout) == 0 {
|
if len(tx.Vout) == 0 {
|
||||||
return ErrNoOutputs
|
return ErrNoOutputs
|
||||||
}
|
}
|
||||||
|
|
||||||
if state.hf4Active && uint64(len(tx.Vout)) < config.TxMinAllowedOutputs {
|
if state.hardForkFourActive && uint64(len(tx.Vout)) < config.TxMinAllowedOutputs {
|
||||||
return coreerr.E("checkOutputs", fmt.Sprintf("%d (min %d)", len(tx.Vout), config.TxMinAllowedOutputs), ErrTooFewOutputs)
|
return coreerr.E("checkOutputs", fmt.Sprintf("%d (min %d)", len(tx.Vout), config.TxMinAllowedOutputs), ErrTooFewOutputs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -171,7 +171,7 @@ func checkOutputs(tx *types.Transaction, state txForkState) error {
|
||||||
switch o.Target.(type) {
|
switch o.Target.(type) {
|
||||||
case types.TxOutToKey:
|
case types.TxOutToKey:
|
||||||
case types.TxOutHTLC, types.TxOutMultisig:
|
case types.TxOutHTLC, types.TxOutMultisig:
|
||||||
if !state.hf1Active {
|
if !state.hardForkOneActive {
|
||||||
return coreerr.E("checkOutputs", fmt.Sprintf("output %d: HTLC/multisig target pre-HF1", i), ErrInvalidOutput)
|
return coreerr.E("checkOutputs", fmt.Sprintf("output %d: HTLC/multisig target pre-HF1", i), ErrInvalidOutput)
|
||||||
}
|
}
|
||||||
case nil:
|
case nil:
|
||||||
|
|
@ -180,7 +180,7 @@ func checkOutputs(tx *types.Transaction, state txForkState) error {
|
||||||
return coreerr.E("checkOutputs", fmt.Sprintf("output %d: unsupported target %T", i, o.Target), ErrInvalidOutput)
|
return coreerr.E("checkOutputs", fmt.Sprintf("output %d: unsupported target %T", i, o.Target), ErrInvalidOutput)
|
||||||
}
|
}
|
||||||
case types.TxOutputZarcanum:
|
case types.TxOutputZarcanum:
|
||||||
if !state.hf4Active {
|
if !state.hardForkFourActive {
|
||||||
return coreerr.E("checkOutputs", fmt.Sprintf("output %d: Zarcanum output pre-HF4", i), ErrInvalidOutput)
|
return coreerr.E("checkOutputs", fmt.Sprintf("output %d: Zarcanum output pre-HF4", i), ErrInvalidOutput)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
@ -211,7 +211,7 @@ func checkKeyImages(tx *types.Transaction) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkAssetOperations(extra []byte, hf5Active bool) error {
|
func checkAssetOperations(extra []byte, hardForkFiveActive bool) error {
|
||||||
if len(extra) == 0 {
|
if len(extra) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -225,7 +225,7 @@ func checkAssetOperations(extra []byte, hf5Active bool) error {
|
||||||
if elem.Tag != types.AssetDescriptorOperationTag {
|
if elem.Tag != types.AssetDescriptorOperationTag {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !hf5Active {
|
if !hardForkFiveActive {
|
||||||
return coreerr.E("checkAssetOperations", fmt.Sprintf("extra[%d]: asset descriptor operation pre-HF5", i), ErrInvalidExtra)
|
return coreerr.E("checkAssetOperations", fmt.Sprintf("extra[%d]: asset descriptor operation pre-HF5", i), ErrInvalidExtra)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ func TestCheckTxVersion_Good(t *testing.T) {
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
err := checkTxVersion(tt.tx, newTxForkState(tt.forks, tt.height), tt.height)
|
err := checkTxVersion(tt.tx, newTransactionForkState(tt.forks, tt.height), tt.height)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("checkTxVersion returned unexpected error: %v", err)
|
t.Errorf("checkTxVersion returned unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -109,7 +109,7 @@ func TestCheckTxVersion_Bad(t *testing.T) {
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
err := checkTxVersion(tt.tx, newTxForkState(tt.forks, tt.height), tt.height)
|
err := checkTxVersion(tt.tx, newTransactionForkState(tt.forks, tt.height), tt.height)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("expected ErrTxVersionInvalid, got nil")
|
t.Error("expected ErrTxVersionInvalid, got nil")
|
||||||
}
|
}
|
||||||
|
|
@ -120,28 +120,28 @@ func TestCheckTxVersion_Bad(t *testing.T) {
|
||||||
func TestCheckTxVersion_Ugly(t *testing.T) {
|
func TestCheckTxVersion_Ugly(t *testing.T) {
|
||||||
// v2 at exact HF4 activation boundary (height 101 on testnet, HF4.Height=100).
|
// v2 at exact HF4 activation boundary (height 101 on testnet, HF4.Height=100).
|
||||||
txHF4 := validV2Tx()
|
txHF4 := validV2Tx()
|
||||||
err := checkTxVersion(txHF4, newTxForkState(config.TestnetForks, 101), 101)
|
err := checkTxVersion(txHF4, newTransactionForkState(config.TestnetForks, 101), 101)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("v2 at HF4 activation boundary should be valid: %v", err)
|
t.Errorf("v2 at HF4 activation boundary should be valid: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// v1 at exact HF4 activation boundary should be rejected.
|
// v1 at exact HF4 activation boundary should be rejected.
|
||||||
txPreHF4 := validV1Tx()
|
txPreHF4 := validV1Tx()
|
||||||
err = checkTxVersion(txPreHF4, newTxForkState(config.TestnetForks, 101), 101)
|
err = checkTxVersion(txPreHF4, newTransactionForkState(config.TestnetForks, 101), 101)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("v1 at HF4 activation boundary should be rejected")
|
t.Error("v1 at HF4 activation boundary should be rejected")
|
||||||
}
|
}
|
||||||
|
|
||||||
// v3 at exact HF5 activation boundary (height 201 on testnet, HF5.Height=200).
|
// v3 at exact HF5 activation boundary (height 201 on testnet, HF5.Height=200).
|
||||||
tx := validV3Tx()
|
tx := validV3Tx()
|
||||||
err = checkTxVersion(tx, newTxForkState(config.TestnetForks, 201), 201)
|
err = checkTxVersion(tx, newTransactionForkState(config.TestnetForks, 201), 201)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("v3 at HF5 activation boundary should be valid: %v", err)
|
t.Errorf("v3 at HF5 activation boundary should be valid: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// v2 at exact HF5 activation boundary — should be rejected.
|
// v2 at exact HF5 activation boundary — should be rejected.
|
||||||
tx2 := validV2Tx()
|
tx2 := validV2Tx()
|
||||||
err = checkTxVersion(tx2, newTxForkState(config.TestnetForks, 201), 201)
|
err = checkTxVersion(tx2, newTransactionForkState(config.TestnetForks, 201), 201)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("v2 at HF5 activation boundary should be rejected")
|
t.Error("v2 at HF5 activation boundary should be rejected")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,9 +49,9 @@ func VerifyTransactionSignatures(tx *types.Transaction, forks []config.HardFork,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
hf4Active := config.IsHardForkActive(forks, config.HF4Zarcanum, height)
|
hardForkFourActive := config.IsHardForkActive(forks, config.HF4Zarcanum, height)
|
||||||
|
|
||||||
if !hf4Active {
|
if !hardForkFourActive {
|
||||||
return verifyV1Signatures(tx, height, getRingOutputs)
|
return verifyV1Signatures(tx, height, getRingOutputs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue