Skip to content

Commit

Permalink
quai_api.go: updated reorg api for new and old headers (dominant-stra…
Browse files Browse the repository at this point in the history
  • Loading branch information
alanorwick authored Jun 30, 2022
1 parent dcdfd0c commit febbb01
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 22 deletions.
42 changes: 37 additions & 5 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -1721,8 +1721,8 @@ func (bc *BlockChain) AddExternalBlock(block *types.ExternalBlock) error {

// ReOrgRollBack compares the difficulty of the newchain and oldchain. Rolls back
// the current header to the position where the reorg took place in a higher context
func (bc *BlockChain) ReOrgRollBack(header *types.Header) error {
log.Info("Rolling back header beyond", "hash", header.Hash())
func (bc *BlockChain) ReOrgRollBack(header *types.Header, validHeaders []*types.Header, invalidHeaders []*types.Header) error {
log.Info("Rolling back header beyond", "hash", header.Hash(), "from", bc.CurrentBlock().Header().Hash())
bc.reorgmu.Lock()
defer bc.reorgmu.Unlock()
var (
Expand Down Expand Up @@ -3073,7 +3073,20 @@ func (bc *BlockChain) PCRC(header *types.Header) (common.Hash, error) {
return common.Hash{}, err
}

// PCRC has failed. Rollback through the prior untwisted region.
if RTZ.Hash() != RTR.Hash() {
log.Info("Error in PCRC", "RTZ:", RTZ.Hash(), "RTR:", RTR.Hash())
// If we are running in Prime or Region and have failed PCRC
// 1. Check to see if the Zone terminus is on our chain.
// 2. If Zone terminus is in our chain, do nothing.
// 3. If Zone terminus is not in our chain, uncle the RTZ in the subordinate context.
if types.QuaiNetworkContext < params.ZONE {
rtz := bc.hc.GetBlockNumber(RTZ.Hash())
// rtz is not in our Region chain, remove it from subordinate chains.
if rtz == nil {
bc.chainUncleFeed.Send(RTZ)
}
}
return common.Hash{}, errors.New("there exists a region twist")
}
}
Expand All @@ -3091,18 +3104,37 @@ func (bc *BlockChain) PCRC(header *types.Header) (common.Hash, error) {

// Only check for prime twist if block is of prime order
if headerOrder == params.PRIME {

PTR, err := bc.Engine().PreviousCoincidentOnPath(bc, header, slice, params.PRIME, params.REGION)
if err != nil {
return common.Hash{}, err
}

PTP, err := bc.Engine().PreviousCoincidentOnPath(bc, header, slice, params.PRIME, params.PRIME)
if err != nil {
return common.Hash{}, err
}

if PTZ.Hash() != PTR.Hash() || PTR.Hash() != PTP.Hash() || PTP.Hash() != PTZ.Hash() {
// PCRC has failed. Rollback through the prior untwisted prime.
if PTR.Hash() != PTP.Hash() {
log.Info("Error in PCRC", "PTR:", PTR.Hash(), "RTR:", PTP.Hash())
if types.QuaiNetworkContext < params.REGION {
ptr := bc.hc.GetBlockNumber(PTR.Hash())
// ptr is not in our Prime chain, remove it from subordinate chains.
if ptr == nil {
bc.chainUncleFeed.Send(PTR)
}
}
return common.Hash{}, errors.New("there exists a prime twist")
}

if PTZ.Hash() != PTR.Hash() {
log.Info("Error in PCRC", "PTZ:", PTZ.Hash(), "PTR:", PTR.Hash())
if types.QuaiNetworkContext < params.REGION {
ptz := bc.hc.GetBlockNumber(PTZ.Hash())
// ptz is not in our Prime chain, remove it from subordinate chains.
if ptz == nil {
bc.chainUncleFeed.Send(PTZ)
}
}
return common.Hash{}, errors.New("there exists a prime twist")
}
}
Expand Down
4 changes: 2 additions & 2 deletions eth/api_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ func (b *EthAPIBackend) AddExternalBlock(block *types.ExternalBlock) error {
return b.eth.blockchain.AddExternalBlock(block)
}

func (b *EthAPIBackend) ReOrgRollBack(header *types.Header) error {
return b.eth.blockchain.ReOrgRollBack(header)
func (b *EthAPIBackend) ReOrgRollBack(header *types.Header, validDoms []*types.Header, invalidDoms []*types.Header) error {
return b.eth.blockchain.ReOrgRollBack(header, validDoms, invalidDoms)
}

func (b *EthAPIBackend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
Expand Down
8 changes: 5 additions & 3 deletions ethclient/ethclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -654,9 +654,11 @@ func (ec *Client) SendExternalBlock(ctx context.Context, block *types.Block, rec
return ec.c.CallContext(ctx, nil, "quai_sendExternalBlock", data)
}

// SendReorgData sends thre reorg data to the node to rollup and update the chain
func (ec *Client) SendReOrgData(ctx context.Context, header *types.Header) error {
data, err := ethapi.RPCMarshalReOrgData(header)
// header: header in which the intended chain is to roll back to.
// newHeaders: potentially now valid dominant headers to take out of nonCanonDom db.
// oldHeaders: invalid dominant headers to insert into nonCanonDom db.
func (ec *Client) SendReOrgData(ctx context.Context, header *types.Header, newHeaders []*types.Header, oldHeaders []*types.Header) error {
data, err := ethapi.RPCMarshalReOrgData(header, newHeaders, oldHeaders)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/ethapi/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ type Backend interface {
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
SubscribeChainUncleEvent(ch chan<- *types.Header) event.Subscription
InsertBlock(ctx context.Context, block *types.Block) (int, error)
ReOrgRollBack(header *types.Header) error
ReOrgRollBack(header *types.Header, validHeaders []*types.Header, invalidHeaders []*types.Header) error
PendingBlockAndReceipts() (*types.Block, types.Receipts)
AddExternalBlock(block *types.ExternalBlock) error
EventMux() *event.TypeMux
Expand Down
34 changes: 24 additions & 10 deletions internal/ethapi/quai_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -491,8 +491,21 @@ func RPCMarshalExternalBlock(block *types.Block, receipts []*types.Receipt, cont
}

// rpcMarshalReOrgData converts the reOrgData obtained to the right header format
func RPCMarshalReOrgData(header *types.Header) (map[string]interface{}, error) {
fields := RPCMarshalHeader(header)
func RPCMarshalReOrgData(header *types.Header, newHeaders []*types.Header, oldHeaders []*types.Header) (map[string]interface{}, error) {
fields := map[string]interface{}{"header": RPCMarshalHeader(header)}

fieldNewHeaders := make([]interface{}, len(newHeaders))
for i, newHeader := range newHeaders {
fieldNewHeaders[i] = RPCMarshalHeader(newHeader)
}

fieldOldHeaders := make([]interface{}, len(oldHeaders))
for i, oldHeader := range oldHeaders {
fieldOldHeaders[i] = RPCMarshalHeader(oldHeader)
}

fields["newHeaders"] = fieldNewHeaders
fields["oldHeaders"] = fieldOldHeaders
return fields, nil
}

Expand Down Expand Up @@ -609,20 +622,21 @@ func (s *PublicBlockChainQuaiAPI) SendMinedBlock(ctx context.Context, raw json.R
return nil
}

type rpcReorgData struct {
Header *types.Header `json:"header"`
NewHeaders []*types.Header `json:"newHeaders"`
OldHeaders []*types.Header `json:"oldHeaders"`
}

// ReOrgRollBack will send the reorg data to perform reorg rollback
func (s *PublicBlockChainQuaiAPI) SendReOrgData(ctx context.Context, raw json.RawMessage) error {
// Decode reOrgHeader and body.
var head *types.Header
var body *types.Header
if err := json.Unmarshal(raw, &head); err != nil {
var reorgData rpcReorgData
if err := json.Unmarshal(raw, &reorgData); err != nil {
return err
}
if err := json.Unmarshal(raw, &body); err != nil {
return err
}

s.b.ReOrgRollBack(head)

s.b.ReOrgRollBack(reorgData.Header, reorgData.NewHeaders, reorgData.OldHeaders)
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion les/api_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func (b *LesApiBackend) AddExternalBlock(block *types.ExternalBlock) error {
return errors.New("light client does not support external block caching.")
}

func (b *LesApiBackend) ReOrgRollBack(header *types.Header) error {
func (b *LesApiBackend) ReOrgRollBack(header *types.Header, validHeaders []*types.Header, invalidHeaders []*types.Header) error {
return errors.New("light client does not support reorg.")
}

Expand Down

0 comments on commit febbb01

Please sign in to comment.