github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/neorpc/result/application_log.go (about)

     1  package result
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  
     8  	"github.com/nspcc-dev/neo-go/pkg/core/state"
     9  	"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
    10  	"github.com/nspcc-dev/neo-go/pkg/util"
    11  )
    12  
    13  // ApplicationLog represent the results of the script executions for a block or a transaction.
    14  type ApplicationLog struct {
    15  	Container     util.Uint256
    16  	IsTransaction bool
    17  	Executions    []state.Execution
    18  }
    19  
    20  // applicationLogAux is an auxiliary struct for ApplicationLog JSON marshalling.
    21  type applicationLogAux struct {
    22  	TxHash     *util.Uint256     `json:"txid,omitempty"`
    23  	BlockHash  *util.Uint256     `json:"blockhash,omitempty"`
    24  	Executions []json.RawMessage `json:"executions"`
    25  }
    26  
    27  // MarshalJSON implements the json.Marshaler interface.
    28  func (l ApplicationLog) MarshalJSON() ([]byte, error) {
    29  	result := &applicationLogAux{
    30  		Executions: make([]json.RawMessage, len(l.Executions)),
    31  	}
    32  	if l.IsTransaction {
    33  		result.TxHash = &l.Container
    34  	} else {
    35  		result.BlockHash = &l.Container
    36  	}
    37  	var err error
    38  	for i := range result.Executions {
    39  		result.Executions[i], err = json.Marshal(l.Executions[i])
    40  		if err != nil {
    41  			return nil, fmt.Errorf("failed to marshal execution #%d: %w", i, err)
    42  		}
    43  	}
    44  	return json.Marshal(result)
    45  }
    46  
    47  // UnmarshalJSON implements the json.Unmarshaler interface.
    48  func (l *ApplicationLog) UnmarshalJSON(data []byte) error {
    49  	aux := new(applicationLogAux)
    50  	if err := json.Unmarshal(data, aux); err != nil {
    51  		return err
    52  	}
    53  	if aux.TxHash != nil {
    54  		l.Container = *aux.TxHash
    55  	} else if aux.BlockHash != nil {
    56  		l.Container = *aux.BlockHash
    57  	} else {
    58  		return errors.New("no block or transaction hash")
    59  	}
    60  	l.Executions = make([]state.Execution, len(aux.Executions))
    61  	for i := range l.Executions {
    62  		err := json.Unmarshal(aux.Executions[i], &l.Executions[i])
    63  		if err != nil {
    64  			return fmt.Errorf("failed to unmarshal execution #%d: %w", i, err)
    65  		}
    66  	}
    67  
    68  	return nil
    69  }
    70  
    71  // NewApplicationLog creates an ApplicationLog from a set of several application execution results
    72  // including only the results with the specified trigger.
    73  func NewApplicationLog(hash util.Uint256, aers []state.AppExecResult, trig trigger.Type) ApplicationLog {
    74  	result := ApplicationLog{
    75  		Container:     hash,
    76  		IsTransaction: aers[0].Trigger == trigger.Application,
    77  	}
    78  	for _, aer := range aers {
    79  		if aer.Trigger&trig != 0 {
    80  			result.Executions = append(result.Executions, aer.Execution)
    81  		}
    82  	}
    83  	return result
    84  }