Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(dot/core): Add only extrinsic during chain reorg. #1609

Merged
merged 11 commits into from
Jun 7, 2021
29 changes: 25 additions & 4 deletions dot/core/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ import (
"github.com/ChainSafe/gossamer/lib/crypto"
"github.com/ChainSafe/gossamer/lib/keystore"
"github.com/ChainSafe/gossamer/lib/runtime"
"github.com/ChainSafe/gossamer/lib/scale"
"github.com/ChainSafe/gossamer/lib/services"
"github.com/ChainSafe/gossamer/lib/transaction"

log "github.com/ChainSafe/log15"
)

Expand Down Expand Up @@ -323,6 +323,11 @@ func (s *Service) handleChainReorg(prev, curr common.Hash) error {
return err
}

// subchain contains the ancestor as well so we need to remove it.
if len(subchain) > 0 {
subchain = subchain[1:]
}

// for each block in the previous chain, re-add its extrinsics back into the pool
for _, hash := range subchain {
body, err := s.blockState.GetBlockBody(hash)
Expand All @@ -340,13 +345,29 @@ func (s *Service) handleChainReorg(prev, curr common.Hash) error {
for _, ext := range exts {
logger.Debug("validating transaction on re-org chain", "extrinsic", ext)

txv, err := s.rt.ValidateTransaction(ext)
decExt := &types.ExtrinsicData{}
err = decExt.DecodeVersion(ext)
if err != nil {
return err
}

// Inherent are not signed.
if !decExt.IsSigned() {
continue
}

encExt, err := scale.Encode(ext)
if err != nil {
return err
}

txv, err := s.rt.ValidateTransaction(append([]byte{byte(types.TxnExternal)}, encExt...))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: move append([]byte{byte(types.TxnExternal)}, encExt...) into it's own line/var

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

if err != nil {
logger.Debug("failed to validate transaction", "extrinsic", ext)
logger.Debug("failed to validate transaction", "error", err, "extrinsic", ext)
continue
}

vtx := transaction.NewValidTransaction(ext, txv)
vtx := transaction.NewValidTransaction(encExt, txv)
s.transactionState.AddToPool(vtx)
}
}
Expand Down
53 changes: 53 additions & 0 deletions dot/core/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

"github.com/ChainSafe/gossamer/dot/network"
"github.com/ChainSafe/gossamer/dot/state"
"github.com/ChainSafe/gossamer/dot/sync"
"github.com/ChainSafe/gossamer/dot/types"
"github.com/ChainSafe/gossamer/lib/common"
"github.com/ChainSafe/gossamer/lib/keystore"
Expand Down Expand Up @@ -166,6 +167,58 @@ func TestHandleChainReorg_NoReorg(t *testing.T) {
require.NoError(t, err)
}

func TestHandleChainReorg_WithReorg_Trans(t *testing.T) {
s := NewTestService(t, nil)

bs := s.blockState

parent, err := bs.BestBlockHeader()
require.NoError(t, err)

syncer := sync.NewTestSyncer(t)

block1 := sync.BuildBlock(t, syncer, parent, nil)
err = bs.AddBlock(block1)
require.NoError(t, err)

block2 := sync.BuildBlock(t, syncer, block1.Header, nil)
err = bs.AddBlock(block2)
require.NoError(t, err)

block3 := sync.BuildBlock(t, syncer, block2.Header, nil)
err = bs.AddBlock(block3)
require.NoError(t, err)

block4 := sync.BuildBlock(t, syncer, block3.Header, nil)
err = bs.AddBlock(block4)
require.NoError(t, err)

block5 := sync.BuildBlock(t, syncer, block4.Header, nil)
err = bs.AddBlock(block5)
require.NoError(t, err)

block31 := sync.BuildBlock(t, syncer, block2.Header, nil)
err = bs.AddBlock(block31)
require.NoError(t, err)

// Add extrinsic to block `block31`
extBytes := sync.CreateExtrinsic(t, syncer)
ext := types.Extrinsic(extBytes)

block41 := sync.BuildBlock(t, syncer, block31.Header, ext)
err = bs.AddBlock(block41)
require.NoError(t, err)

err = s.rt.InitializeBlock(block1.Header)
require.NoError(t, err)

err = s.handleChainReorg(block41.Header.Hash(), block5.Header.Hash())
require.NoError(t, err)

pending := s.transactionState.(*state.TransactionState).Pending()
require.Equal(t, 1, len(pending))
}

func TestHandleChainReorg_WithReorg_NoTransactions(t *testing.T) {
s := NewTestService(t, nil)
height := 5
Expand Down
8 changes: 4 additions & 4 deletions dot/sync/message_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func TestMain(m *testing.M) {
}

func TestService_CreateBlockResponse_MaxSize(t *testing.T) {
s := newTestSyncer(t)
s := NewTestSyncer(t)
addTestBlocksToState(t, int(maxResponseSize), s.blockState)

start, err := variadic.NewUint64OrHash(uint64(1))
Expand Down Expand Up @@ -90,7 +90,7 @@ func TestService_CreateBlockResponse_MaxSize(t *testing.T) {
}

func TestService_CreateBlockResponse_StartHash(t *testing.T) {
s := newTestSyncer(t)
s := NewTestSyncer(t)
addTestBlocksToState(t, int(maxResponseSize), s.blockState)

startHash, err := s.blockState.GetHashByNumber(big.NewInt(1))
Expand All @@ -115,7 +115,7 @@ func TestService_CreateBlockResponse_StartHash(t *testing.T) {
}

func TestService_CreateBlockResponse_Ascending(t *testing.T) {
s := newTestSyncer(t)
s := NewTestSyncer(t)
addTestBlocksToState(t, int(maxResponseSize), s.blockState)

startHash, err := s.blockState.GetHashByNumber(big.NewInt(1))
Expand All @@ -141,7 +141,7 @@ func TestService_CreateBlockResponse_Ascending(t *testing.T) {

// tests the ProcessBlockRequestMessage method
func TestService_CreateBlockResponse(t *testing.T) {
s := newTestSyncer(t)
s := NewTestSyncer(t)
addTestBlocksToState(t, 2, s.blockState)

bestHash := s.blockState.BestBlockHash()
Expand Down
Loading