github.com/MagHErmit/tendermint@v0.282.1/spec/light-client/supervisor/supervisor_002_draft.md (about) 1 # Draft of Light Client Supervisor for discussion 2 3 ## Modification to the initialization 4 5 The lightclient is initialized with LCInitData 6 7 ### **[LC-DATA-INIT.2]** 8 9 ```go 10 type LCInitData struct { 11 TrustedBlock LightBlock 12 Genesis GenesisDoc 13 TrustedHash []byte 14 TrustedHeight int64 15 } 16 ``` 17 18 where only one of the components must be provided. `GenesisDoc` is 19 defined in the [Tendermint 20 Types](https://github.com/MagHErmit/tendermint/blob/v0.34.x/types/genesis.go). 21 22 23 ### Initialization 24 25 The light client is based on subjective initialization. It has to 26 trust the initial data given to it by the user. It cannot perform any 27 detection of an attack yet instead requires an initial point of trust. 28 There are three forms of initial data which are used to obtain the 29 first trusted block: 30 31 - A trusted block from a prior initialization 32 - A trusted height and hash 33 - A genesis file 34 35 The golang light client implementation checks this initial data in that 36 order; first attempting to find a trusted block from the trusted store, 37 then acquiring a light block from the primary at the trusted height and matching 38 the hash, or finally checking for a genesis file to verify the initial header. 39 40 The light client doesn't need to check if the trusted block is within the 41 trusted period because it already trusts it, however, if the light block is 42 outside the trust period, there is a higher chance the light client won't be 43 able to verify anything. 44 45 Cross-checking this trusted block with providers upon initialization is helpful 46 for ensuring that the node is responsive and correctly configured but does not 47 increase trust since proving a conflicting block is a 48 [light client attack](https://github.com/MagHErmit/tendermint/blob/v0.34.x/spec/light-client/detection/detection_003_reviewed.md#tmbc-lc-attack1) 49 and not just a [bogus](https://github.com/MagHErmit/tendermint/blob/v0.34.x/spec/light-client/detection/detection_003_reviewed.md#tmbc-bogus1) block could result in 50 performing backwards verification beyond the trusted period, thus a fruitless 51 endeavour. 52 53 However, with the notion of it's better to fail earlier than later, the golang 54 light client implementation will perform a consistency check on all providers 55 and will error if one returns a different header, allowing the user 56 the opportunity to reinitialize. 57 58 #### **[LC-FUNC-INIT.2]:** 59 60 ```go 61 func InitLightClient(initData LCInitData) (LightStore, Error) { 62 var initialBlock LightBlock 63 64 switch { 65 case LCInitData.TrustedBlock != nil: 66 // we trust the block from a prior initialization 67 initialBlock = LCInitData.TrustedBlock 68 69 case LCInitData.TrustedHash != nil: 70 untrustedBlock := FetchLightBlock(PeerList.Primary(), LCInitData.TrustedHeight) 71 72 73 // verify that the hashes match 74 if untrustedBlock.Hash() != LCInitData.TrustedHash { 75 return nil, Error("Primary returned block with different hash") 76 } 77 // after checking the hash we now trust the block 78 initialBlock = untrustedBlock 79 } 80 case LCInitData.Genesis != nil: 81 untrustedBlock := FetchLightBlock(PeerList.Primary(), LCInitData.Genesis.InitialHeight) 82 83 // verify that 2/3+ of the validator set signed the untrustedBlock 84 if err := VerifyCommitFull(untrustedBlock.Commit, LCInitData.Genesis.Validators); err != nil { 85 return nil, err 86 } 87 88 // we can now trust the block 89 initialBlock = untrustedBlock 90 default: 91 return nil, Error("No initial data was provided") 92 93 // This is done in the golang version but is optional and not strictly part of the protocol 94 if err := CrossCheck(initialBlock, PeerList.Witnesses()); err != nil { 95 return nil, err 96 } 97 98 // initialize light store 99 lightStore := new LightStore; 100 lightStore.Add(newBlock); 101 return (lightStore, OK); 102 } 103 104 func CrossCheck(lb LightBlock, witnesses []Provider) error { 105 for _, witness := range witnesses { 106 witnessBlock := FetchLightBlock(witness, lb.Height) 107 108 if witnessBlock.Hash() != lb.Hash() { 109 return Error("Witness has different block") 110 } 111 } 112 return OK 113 } 114 115 ``` 116 117 - Implementation remark 118 - none 119 - Expected precondition 120 - *LCInitData* contains either a genesis file of a lightblock 121 - if genesis it passes `ValidateAndComplete()` see [Tendermint](https://informal.systems) 122 - Expected postcondition 123 - *lightStore* initialized with trusted lightblock. It has either been 124 cross-checked (from genesis) or it has initial trust from the 125 user. 126 - Error condition 127 - if precondition is violated 128 - empty peerList 129 130 ---- 131