티스토리 뷰

반응형

해당 글은 Hyperledger Fabric 페이지의 게시글을 번역 및 정리한 자료입니다.

원본 사이트 : https://hyperledger-fabric.readthedocs.io/en/release-1.2/pluggable_endorsement_and_validation.html


플러그형 트랜잭션 승인 및 유효성 검사

Motivation

커밋시 트랜잭션의 유효성이 검사되면 피어는 트랜잭션 자체의 상태 변경 사항을 적용하기 전에 다양한 검사를 수행합니다.

  • 트랜잭션에 서명한 ID의 유효성 검사.
  • 트랜잭션에서 엔도서(endorser)의 서명을 확인합니다.
  • 트랜잭션이 해당 체인 코드의 네임 스페이스에 대한 보증 정책을 만족하는지 확인합니다.

다음과 같이 기본 Fabric 유효성 검사 규칙과 다른 사용자 지정 트랜잭션 유효성 검사 규칙을 요구하는 사용 사례가 있습니다.

  • 국가 기반 승인 : 보증 정책이 네임 스페이스뿐 아니라 키에 따라 다를 때.
  • UTXO (미사용 트랜잭션 출력) : 유효성 검사에서 트랜잭션이 입력을 두 배로 사용하지 않는지 여부를 고려할 때.
  • 익명 트랜잭션 : 보증에 피어의 ID가 포함되어 있지 않지만 피어의 ID에 연결할 수없는 서명과 공개 키가 공유되는 경우.

플러그형 보증 및 검증 논리

Fabric은 플러그 코드 방식으로 체인 코드 처리와 관련되도록 사용자 지정 승인 및 유효성 검사 논리를 구현하고 피어에 배포 할 수 있습니다. 이 로직은 선택 가능한 로직으로 구축된 피어로 컴파일되거나 Golang 플러그인으로 피어와 함께 컴파일 및 배포 될 수 있습니다.

모든 체인 코드는 체인 코드 인스턴스 생성시 자체 승인 및 유효성 검증 논리와 연관되어 있음을 상기하십시오. 사용자가 하나를 선택하지 않으면 기본 내장 논리가 내재적으로 선택됩니다. 피어 관리자는 피어의 로컬 구성을 확장하여 피어가 시작할 때 로드 및 적용되는 보증 / 유효성 검사 논리의 사용자 지정을 통해 선택된 보증 / 유효성 검사 논리를 변경할 수 있습니다.


Configuration

각각의 피어는 core.yaml이라는 로컬 설정 파일을 가지고 있고 이는 실행되어야할 승인/유효성 검사와 implementation을 선언합니다.

기본 로직은 ESCC(endorsement의 E)와 VSCC(Validation)으로 불리며 피어 로컬 설정 파일의 handlers 섹션에서 확인할 수 있습니다.

handlers:
    endorsers:
      escc:
        name: DefaultEndorsement
    validators:
      vscc:
        name: DefaultValidation

승인/유효성 검사가 피어에 컴파일됬을 때, name 프로퍼티는 승인/유효성 검사 로직 인스턴스를 만드는 factory를 생성하도록 초기화 function을 만들게 됩니다

해당 function은 HandlerLibrary의 인스턴스 메소드로 core/handlers/library/library.go 디렉토리 아래에서 실행되고 커스텀 승인/유효성 검사 로직을 추가되도록 하기 위해서 사용됩니다.

이는 추가적인 메소드로 확장되기 위해서 필요합니다.

이것이 무겁고 실행하기 어렵다는 점을 제시하기 때문에, 하나가 또한 커스텀 승인/유효성 검사를 library라고 불리는 name 아래에 다른 프로퍼티로 추가하도록 하는 Golang 플러그인으로서 배포할 수 있습니다.

한 예로, 플러그인으로서 실행된 상태 기반 승인을 의미하는 커스텀 승인/유효성 검사를 가지고 있다면, 다음의 엔트리를 core.yaml 파일에 가지고 있을 것입니다.

handlers:
    endorsers:
      escc:
        name: DefaultEndorsement
      statebased:
        name: state_based
        library: /etc/hyperledger/fabric/plugins/state_based_endorsement.so
    validators:
      vscc:
        name: DefaultValidation
      statebased:
        name: state_based
        library: /etc/hyperledger/fabric/plugins/state_based_validation.so

그리고 피어의 로컬 파일 시스템에 .so 플러그인 파일을 포함해야 합니다.


이 지점 이후로, 피어에 의해서 컴파일이 되었을 때도 커스텀 승인/유효성 검사 로직은 플러그인으로 표현될 것입니다.


Endorsement Plugin implementation

승인 플러그인을 실행하기 위해서, core/handlers/endorsement/api/endorsement.go 디렉토리의 Plugin 인터페이스를 선행적으로 실행해야합니다.

// Plugin endorses a proposal response
type Plugin interface {
    // Endorse signs the given payload(ProposalResponsePayload bytes), and optionally mutates it.
    // Returns:
    // The Endorsement: A signature over the payload, and an identity that is used to verify the signature
    // The payload that was given as input (could be modified within this function)
    // Or error on failure
    Endorse(payload []byte, sp *peer.SignedProposal) (*peer.Endorsement, []byte, error)

    // Init injects dependencies into the instance of the Plugin
    Init(dependencies ...Dependency) error
}

주어진 플러그인 타입의 승인 플러그인 인스턴스(HandlerLibrary의 인스턴스 메소드로 메소드 이름이 식별되거나 .so 플러그인 파일 경로로 식별됩니다)는 각각의 채널 내 플러그인 개발자들이 사용할 수 있는 PluginFactory 인터페이스를 이용해서 피어들이 New 메소드를 인보크 하면서 생성됩니다.

// PluginFactory creates a new instance of a Plugin
type PluginFactory interface {
    New() Plugin
}

Init 메소드는 core/handlers/endorsement/api/ 디렉토리 아래에 모든 의존성 인풋을 수용하고, 의존성 인퍼페이스를 내장하는 것으로 식별됩니다.

플러그인 인터페이스를 생성한 이후에, Init 메소드가 피어들에 의해서 dependencies를 파라미터로 사용하여 인보크 됩니다.

현재 Fabric은 승인 플러그인은 다음과 같은 의존성을 포함하고 있습니다.

SigningIdentityFetcher: 주어진 서명 제안을 기반으로 한 SigningIdentity의 인스턴스를 리턴합니다.

// SigningIdentity signs messages and serializes its public identity to bytes
type SigningIdentity interface {
    // Serialize returns a byte representation of this identity which is used to verify
    // messages signed by this SigningIdentity
    Serialize() ([]byte, error)

    // Sign signs the given payload and returns a signature
    Sign([]byte) ([]byte, error)
}

StateFetcher: world state와 상호작용 하고 있는 State 객체를 가져옵니다.

// State defines interaction with the world state
type State interface {
    // GetPrivateDataMultipleKeys gets the values for the multiple private data items in a single call
    GetPrivateDataMultipleKeys(namespace, collection string, keys []string) ([][]byte, error)

    // GetStateMultipleKeys gets the values for multiple keys in a single call
    GetStateMultipleKeys(namespace string, keys []string) ([][]byte, error)

    // GetTransientByTXID gets the values private data associated with the given txID
    GetTransientByTXID(txID string) ([]*rwset.TxPvtReadWriteSet, error)

    // Done releases resources occupied by the State
    Done()
 }


Validation plugin implementation

유효성 검사 플러그인을 실행하기 위해선, core/handlers/validation/api/validation.go 디렉토리의 Plugin 인터페이스가 실행되어야만 합니다.

// Plugin validates transactions
type Plugin interface {
    // Validate returns nil if the action at the given position inside the transaction
    // at the given position in the given block is valid, or an error if not.
    Validate(block *common.Block, namespace string, txPosition int, actionPosition int, contextData ...ContextDatum) error

    // Init injects dependencies into the instance of the Plugin
    Init(dependencies ...Dependency) error
}

각각의 ContextDatum은 피어에서 유효성 검사 플러그인으로 전송된 추가적인 실행 중 메타데이터입니다. 현재, ContextDatum은 Chaincode의 endorsement 정책을 표현합니다.

 // SerializedPolicy defines a serialized policy
type SerializedPolicy interface {
      validation.ContextDatum

      // Bytes returns the bytes of the SerializedPolicy
      Bytes() []byte
 }

주어진 플러그인 타입의 유효성 검사 플러그인 인스턴스(HandlerLibrary의 인스턴스 메소드로 메소드 이름이 식별되거나 .so 플러그인 파일 경로로 식별됩니다)는 각각의 채널 내 플러그인 개발자들이 사용할 수 있는 PluginFactory 인터페이스를 이용해서 피어들이 New 메소드를 인보크 하면서 생성됩니다.

// PluginFactory creates a new instance of a Plugin
type PluginFactory interface {
    New() Plugin
}

Init 메소드는 core/handlers/validation/api/ 디렉토리 아래에 모든 의존성 인풋을 수용하고, 의존성 인퍼페이스를 내장하는 것으로 식별됩니다.

플러그인 인터페이스를 생성한 이후에, Init 메소드가 피어들에 의해서 dependencies를 파라미터로 사용하여 인보크 됩니다.

현재 Fabric은 유효성 검사 플러그인은 다음과 같은 의존성을 포함하고 있습니다.

IdentityDeserializer: 신원 바이트 데이터를 Identity 객체로 전화함으로서 사용자의 서명을 인증하는데 사용할 수 있고, 해당하는 MSP에 유효성 검사를 하고, 사용자에게 해당되는 MSP Principal에 적합한지 알 수 있습니다.

총 설명서는 core/handlers/validation/identities/identities.go에서 확인하실 수 있습니다.

PolicyEvaluator: 주어진 정책을 충족하는지 평가합니다.

// PolicyEvaluator evaluates policies
type PolicyEvaluator interface {
    validation.Dependency

    // Evaluate takes a set of SignedData and evaluates whether this set of signatures satisfies
    // the policy with the given bytes
    Evaluate(policyBytes []byte, signatureSet []*common.SignedData) error
}

StateFetcher: world state와 상호작용 하고 있는 State 객체를 가져옵니다.

// State defines interaction with the world state
type State interface {
    // GetStateMultipleKeys gets the values for multiple keys in a single call
    GetStateMultipleKeys(namespace string, keys []string) ([][]byte, error)

    // GetStateRangeScanIterator returns an iterator that contains all the key-values between given key ranges.
    // startKey is included in the results and endKey is excluded. An empty startKey refers to the first available key
    // and an empty endKey refers to the last available key. For scanning all the keys, both the startKey and the endKey
    // can be supplied as empty strings. However, a full scan should be used judiciously for performance reasons.
    // The returned ResultsIterator contains results of type *KV which is defined in protos/ledger/queryresult.
    GetStateRangeScanIterator(namespace string, startKey string, endKey string) (ResultsIterator, error)

    // Done releases resources occupied by the State
    Done()
}


Important notes

  • 피어 간 유효성 검사 플러그인 일관성: 차후 릴리즈 버전에선, Fabric 채널 인프라는 채널 내 모든 피어들에 의해서 주어진 Chaincode에 대해 같은 유효성 검증 로직을 블록체인 height에 사용한다는 것을 보장할 것 입니다. 이를 통해 피어들 간에 우연히 발생할 수 있는 각기 다른 실행 결과에 따른 상태 분기로 인한 설정 오류를 제거할 수 있습니다. 그러나 현재까지는 시스템 오퍼레이터와 관리자만이 이러한 현상이 생기지 않았다는 것을 보증할 수 있는 유일한 책임권한자입니다.
  • 유효성 검사 플러그인 에러 핸들링: 데이터베이스에 접근할 수 없는 것과 같이 몇몇 일시적인 실행 문제 때문에 유효성 검사 플러그인이 주어진 트랜잭션이 유효성 여부를 결정하지 못할 때마다 core/handlers/validation/api/validation.go에 정의되어있는 ExecutionFailureError 타입으로 오류 결과를 리턴하게 됩니다. 리턴된 다른 에러들은, 승인 정책 에러로 다루어지고 유효성 검사 로직에 의해서 유효하지 않은 트랜잭션이라는 것을 표시합니다. 그러나 ExecutionFailureError가 리턴되면, 트랜잭션 유효성 요부 표기를 하지 않는 대신에 체인의 프로세싱을 멈춥니다. 이것은 각기 다른 피어 간에 상태 분기를 예방하기 위해서 입니다.
  • 플러그인에 Fabric 코드 임포트: 플러그인 일부 protobuf 이외의 Fabric에 속한 코드를 가져 오는 것은 매우 바람직하지 않으며, 릴리스간에 Fabric 코드가 변경되거나 혼합 피어 버전을 실행할 때 작동 불능 문제가 발생할 수있는 문제가 발생할 수 있습니다. 이상적으로, 플러그인 코드는 제공된 종속성만을 사용해야하며 protobuf 이외의 최소값을 가져와야합니다.


반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함