Skip to content

Commit

Permalink
feat(multiaddr):Support more activate producer txs in one block
Browse files Browse the repository at this point in the history
  • Loading branch information
Houshoupei84 authored and RainFallsSilent committed May 22, 2023
1 parent 653cd1f commit b3e8833
Show file tree
Hide file tree
Showing 3 changed files with 200 additions and 30 deletions.
34 changes: 31 additions & 3 deletions mempool/conflictfunc.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,14 +223,42 @@ func strCancelProducerOwnerPublicKey(tx interfaces.Transaction) (interface{},
return common.BytesToHexString(p.OwnerKey), nil
}

func strActivateAndCancelKeys(tx interfaces.Transaction) (interface{},
func strActivateKey(tx interfaces.Transaction) (interface{},
error) {
if tx.TxType() != common2.CancelProducer && tx.TxType() != common2.ActivateProducer {
if tx.TxType() != common2.ActivateProducer {
err := fmt.Errorf(
"invalid tx:%s", tx.Hash())
return nil, errors.Simple(errors.ErrTxPoolFailure, err)
}
return "activatecancel", nil
p, ok := tx.Payload().(*payload.ActivateProducer)
if !ok {
return nil, fmt.Errorf(
"activate producer payload cast failed, tx:%s", tx.Hash())
}
return common.BytesToHexString(p.NodePublicKey), nil

}

func strCancelKey(tx interfaces.Transaction) (interface{},
error) {
if tx.TxType() != common2.CancelProducer {
err := fmt.Errorf(
"invalid tx:%s", tx.Hash())
return nil, errors.Simple(errors.ErrTxPoolFailure, err)
}
p, ok := tx.Payload().(*payload.ProcessProducer)
if !ok {
err := fmt.Errorf(
"cancel producer payload cast failed, tx:%s", tx.Hash())
return nil, errors.Simple(errors.ErrTxPoolFailure, err)
}
producer := blockchain.DefaultLedger.Blockchain.GetState().GetProducer(p.OwnerKey)
if producer == nil {
err := fmt.Errorf(
"cancel producer GetProducer(p.OwnerKey) failed, tx:%s", tx.Hash())
return nil, errors.Simple(errors.ErrTxPoolFailure, err)
}
return common.BytesToHexString(producer.NodePublicKey()), nil
}

func strProducerInfoOwnerPublicKey(tx interfaces.Transaction) (interface{}, error) {
Expand Down
4 changes: 2 additions & 2 deletions mempool/conflictmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,11 @@ func newConflictManager() conflictManager {
slot: newConflictSlot(str,
keyTypeFuncPair{
Type: common2.CancelProducer,
Func: strActivateAndCancelKeys,
Func: strCancelKey,
},
keyTypeFuncPair{
Type: common2.ActivateProducer,
Func: strActivateAndCancelKeys,
Func: strActivateKey,
},
),
},
Expand Down
192 changes: 167 additions & 25 deletions mempool/conflictmanager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ import (
"github.com/elastos/Elastos.ELA/core/contract"
"github.com/elastos/Elastos.ELA/core/contract/program"
transaction2 "github.com/elastos/Elastos.ELA/core/transaction"
"github.com/elastos/Elastos.ELA/core/types"
common2 "github.com/elastos/Elastos.ELA/core/types/common"
"github.com/elastos/Elastos.ELA/core/types/functions"
"github.com/elastos/Elastos.ELA/core/types/interfaces"
"github.com/elastos/Elastos.ELA/core/types/payload"
"github.com/elastos/Elastos.ELA/crypto"
"github.com/elastos/Elastos.ELA/dpos/state"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -66,13 +68,90 @@ func TestConflictManager_DPoS_OwnerPublicKey(t *testing.T) {
0,
[]*program.Program{},
)
tx4 := functions.CreateTransaction(
0,
common2.RegisterCR,
0,
&payload.CRInfo{
Code: redeemScriptFromPk(pk),
},
[]*common2.Attribute{},
[]*common2.Input{},
[]*common2.Output{},
0,
[]*program.Program{},
)

tx3 := functions.CreateTransaction(
txs := []interfaces.Transaction{tx1, tx2, tx4} //tx3,
verifyTxListWithConflictManager(txs, db, true, t)
})

conflictTestProc(func(db *UtxoCacheDB) {
currentHeight := uint32(1)
dposState := blockchain.DefaultLedger.Blockchain.GetState()
ownerPK1 := randomPublicKey()
NodePublicKey1 := randomPublicKey()
ownerPK2 := randomPublicKey()
NodePublicKey2 := randomPublicKey()
regProTX1 := functions.CreateTransaction(
0,
common2.RegisterProducer,
0,
&payload.ProducerInfo{
OwnerKey: ownerPK1,
NodePublicKey: NodePublicKey1,
NickName: randomNickname(),
},
[]*common2.Attribute{},
[]*common2.Input{},
[]*common2.Output{},
0,
[]*program.Program{},
)
regProTX2 := functions.CreateTransaction(
0,
common2.RegisterProducer,
0,
&payload.ProducerInfo{
OwnerKey: ownerPK2,
NodePublicKey: NodePublicKey2,
NickName: randomNickname(),
},
[]*common2.Attribute{},
[]*common2.Input{},
[]*common2.Output{},
0,
[]*program.Program{},
)
block := &types.Block{
Transactions: []interfaces.Transaction{
regProTX1,
regProTX2,
},
Header: common2.Header{Height: currentHeight},
}
dposState.ProcessBlock(block, nil, 0)
currentHeight++

CancelProTX1 := functions.CreateTransaction(
0,
common2.CancelProducer,
0,
&payload.ProcessProducer{
OwnerKey: ownerPK1,
},
[]*common2.Attribute{},
[]*common2.Input{},
[]*common2.Output{},
0,
[]*program.Program{},
)
CancelProTX2 := functions.CreateTransaction(
0,
common2.CancelProducer,
0,
&payload.ProcessProducer{
OwnerKey: pk,
OwnerKey: ownerPK2,
},
[]*common2.Attribute{},
[]*common2.Input{},
Expand All @@ -81,22 +160,87 @@ func TestConflictManager_DPoS_OwnerPublicKey(t *testing.T) {
[]*program.Program{},
)

tx4 := functions.CreateTransaction(
activProTX1 := functions.CreateTransaction(
0,
common2.RegisterCR,
common2.ActivateProducer,
0,
&payload.CRInfo{
Code: redeemScriptFromPk(pk),
&payload.ActivateProducer{
NodePublicKey: NodePublicKey1,
},
[]*common2.Attribute{},
[]*common2.Input{},
[]*common2.Output{},
0,
[]*program.Program{},
)
activProTX2 := functions.CreateTransaction(
0,
common2.ActivateProducer,
0,
&payload.ActivateProducer{
NodePublicKey: NodePublicKey2,
},
[]*common2.Attribute{},
[]*common2.Input{},
[]*common2.Output{},
0,
[]*program.Program{},
)
//register two different producer at the same time
{
manager := newConflictManager()
assert.NoError(t, manager.VerifyTx(regProTX1))
assert.NoError(t, manager.AppendTx(regProTX1))
assert.NoError(t, manager.VerifyTx(regProTX2))
assert.NoError(t, manager.AppendTx(regProTX2))
}
//activate two different producers at the same time
{
manager := newConflictManager()
assert.NoError(t, manager.VerifyTx(activProTX1))
assert.NoError(t, manager.AppendTx(activProTX1))
assert.NoError(t, manager.VerifyTx(activProTX2))
assert.NoError(t, manager.AppendTx(activProTX2))
}
//activate two different producers at the same time
{
manager := newConflictManager()
assert.NoError(t, manager.VerifyTx(activProTX1))
assert.NoError(t, manager.AppendTx(activProTX1))
assert.NoError(t, manager.VerifyTx(activProTX2))
assert.NoError(t, manager.AppendTx(activProTX2))
}

//cancel two different producers at the same time
{
manager := newConflictManager()
assert.NoError(t, manager.VerifyTx(CancelProTX1))
assert.NoError(t, manager.AppendTx(CancelProTX1))
assert.NoError(t, manager.VerifyTx(CancelProTX2))
assert.NoError(t, manager.AppendTx(CancelProTX2))
}

//active and cancel one producer at the same time must report error
{
manager := newConflictManager()
assert.NoError(t, manager.VerifyTx(CancelProTX1))
assert.NoError(t, manager.AppendTx(CancelProTX1))
//assert.NoError(t, manager.VerifyTx(activProTX1))
err := manager.VerifyTx(activProTX1)
assert.Error(t, err, "slot DPoSActivateCancel verify tx error")
//no need append
//assert.NoError(t, manager.AppendTx(activProTX1))
}

//active and cancel diffrent producers at the same time
{
manager := newConflictManager()
assert.NoError(t, manager.VerifyTx(CancelProTX1))
assert.NoError(t, manager.AppendTx(CancelProTX1))
assert.NoError(t, manager.VerifyTx(activProTX2))
assert.NoError(t, manager.AppendTx(activProTX2))
}

txs := []interfaces.Transaction{tx1, tx2, tx3, tx4}
verifyTxListWithConflictManager(txs, db, true, t)
})
}

Expand Down Expand Up @@ -722,21 +866,6 @@ func TestConflictManager_InputInferKeys(t *testing.T) {
0,
[]*program.Program{},
)

tx3 := functions.CreateTransaction(
0,
common2.CancelProducer,
0,
&payload.ProcessProducer{
OwnerKey: randomPublicKey(),
},
[]*common2.Attribute{},
[]*common2.Input{},
[]*common2.Output{},
0,
[]*program.Program{},
)

tx4 := functions.CreateTransaction(
0,
common2.RegisterCR,
Expand Down Expand Up @@ -894,8 +1023,7 @@ func TestConflictManager_InputInferKeys(t *testing.T) {
0,
[]*program.Program{},
)

txs := []interfaces.Transaction{tx1, tx2, tx3, tx4, tx5, tx6, tx7, tx8, tx9, tx10, tx11, tx12, tx13, tx14}
txs := []interfaces.Transaction{tx1, tx2, tx4, tx5, tx6, tx7, tx8, tx9, tx10, tx11, tx12, tx13, tx14}

verifyTxListWithConflictManager(txs, db, false, t)
})
Expand All @@ -909,6 +1037,20 @@ func conflictTestProc(action func(*UtxoCacheDB)) {
UTXOCache: blockchain.NewUTXOCache(utxoCacheDB, &config.DefaultParams),
},
}

blockchain.DefaultLedger.Blockchain.SetState(state.NewState(&config.DefaultParams, nil, nil, nil,
func() bool { return false }, func(programHash common.Uint168) (common.Fixed64,
error) {
amount := common.Fixed64(0)
utxos, err := blockchain.DefaultLedger.Blockchain.GetDB().GetFFLDB().GetUTXO(&programHash)
if err != nil {
return amount, err
}
for _, utxo := range utxos {
amount += utxo.Value
}
return amount, nil
}, nil, nil, nil, nil, nil, nil))
action(utxoCacheDB)
blockchain.DefaultLedger = origin
}
Expand Down

0 comments on commit b3e8833

Please sign in to comment.