github.com/koko1123/flow-go-1@v0.29.6/model/chunks/chunkFaults.go (about)

     1  package chunks
     2  
     3  import (
     4  	"encoding/hex"
     5  	"fmt"
     6  
     7  	"github.com/koko1123/flow-go-1/model/flow"
     8  )
     9  
    10  // ChunkFault holds information about a fault that is found while
    11  // verifying a chunk
    12  type ChunkFault interface {
    13  	ChunkIndex() uint64
    14  	ExecutionResultID() flow.Identifier
    15  	String() string
    16  }
    17  
    18  // CFMissingRegisterTouch is returned when a register touch is missing (read or update)
    19  type CFMissingRegisterTouch struct {
    20  	regsterIDs []string
    21  	chunkIndex uint64
    22  	execResID  flow.Identifier
    23  	txID       flow.Identifier // very first transaction inside the chunk that required this register
    24  }
    25  
    26  func (cf CFMissingRegisterTouch) String() string {
    27  	hexStrings := make([]string, len(cf.regsterIDs))
    28  	for i, s := range cf.regsterIDs {
    29  		hexStrings[i] = hex.EncodeToString([]byte(s))
    30  	}
    31  
    32  	return fmt.Sprintf("at least one register touch was missing inside the chunk data package that was needed while running transactions of chunk %d of result %s (tx hash of one of them: %s), hex-encoded register ids: %s", cf.chunkIndex, cf.execResID.String(), cf.txID.String(), hexStrings)
    33  }
    34  
    35  // ChunkIndex returns chunk index of the faulty chunk
    36  func (cf CFMissingRegisterTouch) ChunkIndex() uint64 {
    37  	return cf.chunkIndex
    38  }
    39  
    40  // ExecutionResultID returns the execution result identifier including the faulty chunk
    41  func (cf CFMissingRegisterTouch) ExecutionResultID() flow.Identifier {
    42  	return cf.execResID
    43  }
    44  
    45  // NewCFMissingRegisterTouch creates a new instance of Chunk Fault (MissingRegisterTouch)
    46  func NewCFMissingRegisterTouch(regsterIDs []string, chInx uint64, execResID flow.Identifier, txID flow.Identifier) *CFMissingRegisterTouch {
    47  	return &CFMissingRegisterTouch{regsterIDs: regsterIDs,
    48  		chunkIndex: chInx,
    49  		execResID:  execResID,
    50  		txID:       txID}
    51  }
    52  
    53  // CFNonMatchingFinalState is returned when the computed final state commitment
    54  // (applying chunk register updates to the partial trie) doesn't match the one provided by the chunk
    55  type CFNonMatchingFinalState struct {
    56  	expected   flow.StateCommitment
    57  	computed   flow.StateCommitment
    58  	chunkIndex uint64
    59  	execResID  flow.Identifier
    60  }
    61  
    62  func (cf CFNonMatchingFinalState) String() string {
    63  	return fmt.Sprintf("final state commitment doesn't match, expected [%x] but computed [%x]", cf.expected, cf.computed)
    64  }
    65  
    66  // ChunkIndex returns chunk index of the faulty chunk
    67  func (cf CFNonMatchingFinalState) ChunkIndex() uint64 {
    68  	return cf.chunkIndex
    69  }
    70  
    71  // ExecutionResultID returns the execution result identifier including the faulty chunk
    72  func (cf CFNonMatchingFinalState) ExecutionResultID() flow.Identifier {
    73  	return cf.execResID
    74  }
    75  
    76  // NewCFNonMatchingFinalState creates a new instance of Chunk Fault (NonMatchingFinalState)
    77  func NewCFNonMatchingFinalState(expected flow.StateCommitment, computed flow.StateCommitment, chInx uint64, execResID flow.Identifier) *CFNonMatchingFinalState {
    78  	return &CFNonMatchingFinalState{expected: expected,
    79  		computed:   computed,
    80  		chunkIndex: chInx,
    81  		execResID:  execResID}
    82  }
    83  
    84  // CFInvalidEventsCollection is returned when computed events collection hash is different from the chunk's one
    85  type CFInvalidEventsCollection struct {
    86  	expected   flow.Identifier
    87  	computed   flow.Identifier
    88  	chunkIndex uint64
    89  	resultID   flow.Identifier
    90  	eventIDs   flow.IdentifierList
    91  }
    92  
    93  func NewCFInvalidEventsCollection(expected flow.Identifier, computed flow.Identifier, chInx uint64, execResID flow.Identifier, events flow.EventsList) *CFInvalidEventsCollection {
    94  	return &CFInvalidEventsCollection{
    95  		expected:   expected,
    96  		computed:   computed,
    97  		chunkIndex: chInx,
    98  		resultID:   execResID,
    99  		eventIDs:   flow.GetIDs(events),
   100  	}
   101  }
   102  
   103  func (c *CFInvalidEventsCollection) ChunkIndex() uint64 {
   104  	return c.chunkIndex
   105  }
   106  
   107  func (c *CFInvalidEventsCollection) ExecutionResultID() flow.Identifier {
   108  	return c.resultID
   109  }
   110  
   111  func (c *CFInvalidEventsCollection) String() string {
   112  	return fmt.Sprintf("events collection hash differs, got %x expected %x for chunk %d with result ID %s, events IDs: %v", c.computed, c.expected,
   113  		c.chunkIndex, c.resultID, c.eventIDs)
   114  }
   115  
   116  // CFInvalidServiceEventsEmitted is returned when service events are different from the chunk's one
   117  type CFInvalidServiceEventsEmitted struct {
   118  	expected   flow.ServiceEventList
   119  	computed   flow.ServiceEventList
   120  	chunkIndex uint64
   121  	resultID   flow.Identifier
   122  }
   123  
   124  func CFInvalidServiceSystemEventsEmitted(expected flow.ServiceEventList, computed flow.ServiceEventList, chInx uint64, execResID flow.Identifier) *CFInvalidServiceEventsEmitted {
   125  	return &CFInvalidServiceEventsEmitted{
   126  		expected:   expected,
   127  		computed:   computed,
   128  		chunkIndex: chInx,
   129  		resultID:   execResID,
   130  	}
   131  }
   132  
   133  func (c *CFInvalidServiceEventsEmitted) ChunkIndex() uint64 {
   134  	return c.chunkIndex
   135  }
   136  
   137  func (c *CFInvalidServiceEventsEmitted) ExecutionResultID() flow.Identifier {
   138  	return c.resultID
   139  }
   140  
   141  func (c *CFInvalidServiceEventsEmitted) String() string {
   142  	return fmt.Sprintf("service events differs, got [%s] expected [%s] for chunk %d with result ID %s", c.computed, c.expected, c.chunkIndex, c.resultID)
   143  }
   144  
   145  // CFInvalidVerifiableChunk is returned when a verifiable chunk is invalid
   146  // this includes cases that code fails to construct a partial trie,
   147  // collection hashes doesn't match
   148  // TODO break this into more detailed ones as we progress
   149  type CFInvalidVerifiableChunk struct {
   150  	reason     string
   151  	details    error
   152  	chunkIndex uint64
   153  	execResID  flow.Identifier
   154  }
   155  
   156  func (cf CFInvalidVerifiableChunk) String() string {
   157  	return fmt.Sprint("invalid verifiable chunk due to ", cf.reason, cf.details.Error())
   158  }
   159  
   160  // ChunkIndex returns chunk index of the faulty chunk
   161  func (cf CFInvalidVerifiableChunk) ChunkIndex() uint64 {
   162  	return cf.chunkIndex
   163  }
   164  
   165  // ExecutionResultID returns the execution result identifier including the faulty chunk
   166  func (cf CFInvalidVerifiableChunk) ExecutionResultID() flow.Identifier {
   167  	return cf.execResID
   168  }
   169  
   170  // NewCFInvalidVerifiableChunk creates a new instance of Chunk Fault (InvalidVerifiableChunk)
   171  func NewCFInvalidVerifiableChunk(reason string, err error, chInx uint64, execResID flow.Identifier) *CFInvalidVerifiableChunk {
   172  	return &CFInvalidVerifiableChunk{reason: reason,
   173  		details:    err,
   174  		chunkIndex: chInx,
   175  		execResID:  execResID}
   176  }