-
Notifications
You must be signed in to change notification settings - Fork 2
/
main.go
77 lines (67 loc) · 3.8 KB
/
main.go
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package main
import (
"fmt"
"github.com/almog-t/light-client-poc/encodedassets"
"github.com/almog-t/light-client-poc/oracle"
"github.com/almog-t/light-client-poc/transactionverifier"
)
// A light client is composed of two modules:
// 1. An oracle, in charge of maintaining Algorand's state as verified with state proofs. For more details, see oracle.go.
// 2. A transaction verifier, in charge of verifying Algorand transaction occurrence by interfacing with the oracle. For more
// details, see transactionVerifier.go.
// This main function aims to demonstrate the interface between these two modules. In an actual
// light client, they can be entirely separate processes/smart contracts.
// The oracle should receive Algorand data from an off chain relayer, and the transaction verifier should receive
// transaction occurrence queries from third parties. For the purposes of this PoC, they're two separate go packages, and
// both the relayer and other third parties have been replaced with example committed data.
func main() {
// This is the genesis data, required for initializing the oracle. This data can either be queried from the
// blockchain itself, or found in the developer's portal.
genesisVotersCommitment, genesisVotersLnProvenWeight, err := encodedassets.GetParsedGenesisData("encodedassets/genesis/")
if err != nil {
fmt.Printf("Failed to parse genesis assets: %s\n", err)
return
}
// This is data required for verifying a transaction. In a real light client, this data should come from a
// third party. The third party is responsible for querying Algorand to get most of this data.
genesisHash, round, seed, transactionHash, transactionProofResponse, lightBlockHeaderProofResponse, err :=
encodedassets.GetParsedTypesData("encodedassets/transactionverification/")
if err != nil {
fmt.Printf("Failed to parse assets needed for transaction verification: %s\n", err)
return
}
// This is data required for advancing the oracle's state. In a real light client, this data should come from a relayer.
stateProofMessage, stateProof, err :=
encodedassets.GetParsedStateProofAdvancmentData("encodedassets/stateproofverification/")
if err != nil {
fmt.Printf("Failed to parse assets needed for oracle state advancement: %s\n", err)
return
}
// In a real light client, intervalSize and firstAttestedRound should be hardcoded, and retrieved from the Algorand
// consensus and from the Algorand blockchain respectively.
intervalSize := uint64(8)
firstAttestedRound := uint64(9)
// We initialize the oracle using the parsed genesis data and a hard coded capacity.
oracleInstance := oracle.InitializeOracle(firstAttestedRound, intervalSize, genesisVotersCommitment, genesisVotersLnProvenWeight, 1000)
// We advance the oracle's state using the state proof and the state proof message. The oracle verifies the message
// using the state proof. See the documentation in oracle.go for more details.
err = oracleInstance.AdvanceState(stateProof, stateProofMessage)
if err != nil {
fmt.Printf("Failed to advance oracle state: %s\n", err)
return
}
// After advancing the oracle's state, we retrieve the block interval commitment containing the given transaction's round from the oracle.
desiredTransactionCommitment, err := oracleInstance.GetStateProofCommitment(round)
if err != nil {
fmt.Printf("Failed to retrieve commitment interval for round %d: %s\n", round, err)
return
}
// We then verify the transaction's occurrence using the data provided for transaction verification,
// along with the block interval commitment this transaction belongs to.
err = transactionverifier.VerifyTransaction(transactionHash, transactionProofResponse,
lightBlockHeaderProofResponse, round, genesisHash, seed, desiredTransactionCommitment)
if err != nil {
fmt.Printf("Transaction verification failed: %s\n", err)
return
}
}