forked from hyperledger-labs/yui-ibc-solidity
/
client.go
133 lines (113 loc) · 3.19 KB
/
client.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package testing
import (
"context"
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/common"
gethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/hyperledger-labs/yui-ibc-solidity/pkg/chains"
"github.com/hyperledger-labs/yui-ibc-solidity/pkg/client"
ibcclient "github.com/hyperledger-labs/yui-ibc-solidity/pkg/ibc/client"
)
type LightClient struct {
client *client.ETHClient
clientType string
}
func NewLightClient(cl *client.ETHClient, clientType string) *LightClient {
return &LightClient{client: cl, clientType: clientType}
}
type LightClientState interface {
Header() *gethtypes.Header
Proof() *client.StateProof
}
func (lc LightClient) ClientType() string {
return lc.clientType
}
func (lc LightClient) GetState(ctx context.Context, address common.Address, storageKeys [][]byte, bn *big.Int) (LightClientState, error) {
switch lc.clientType {
case ibcclient.BesuIBFT2Client:
return lc.GetIBFT2State(ctx, address, storageKeys, bn)
case ibcclient.MockClient:
return lc.GetMockContractState(ctx, address, storageKeys, bn)
default:
panic(fmt.Sprintf("unknown client type '%v'", lc.clientType))
}
}
func (lc LightClient) GetMockContractState(ctx context.Context, address common.Address, storageKeys [][]byte, bn *big.Int) (LightClientState, error) {
block, err := lc.client.BlockByNumber(ctx, bn)
if err != nil {
return nil, err
}
// this is dummy
proof := &client.StateProof{
StorageProofRLP: make([][]byte, len(storageKeys)),
}
return ETHState{header: block.Header(), StateProof: proof}, nil
}
func (lc LightClient) GetIBFT2State(ctx context.Context, address common.Address, storageKeys [][]byte, bn *big.Int) (LightClientState, error) {
var state IBFT2State
block, err := lc.client.BlockByNumber(ctx, bn)
if err != nil {
return nil, err
}
proof, err := lc.client.GetStateProof(address, storageKeys, block.Number())
if err != nil {
return nil, err
}
state.StateProof = proof
state.ParsedHeader, err = chains.ParseHeader(block.Header())
if err != nil {
return nil, err
}
state.CommitSeals, err = state.ParsedHeader.ValidateAndGetCommitSeals()
if err != nil {
return nil, err
}
return state, nil
}
type ETHState struct {
header *gethtypes.Header
StateProof *client.StateProof
}
var _ LightClientState = (*ETHState)(nil)
func (cs ETHState) Header() *gethtypes.Header {
return cs.header
}
func (cs ETHState) Proof() *client.StateProof {
return cs.StateProof
}
type IBFT2State struct {
ParsedHeader *chains.ParsedHeader
StateProof *client.StateProof
CommitSeals [][]byte
}
func (cs IBFT2State) Header() *gethtypes.Header {
return cs.ParsedHeader.Base
}
func (cs IBFT2State) Proof() *client.StateProof {
return cs.StateProof
}
func (cs IBFT2State) ChainHeaderRLP() []byte {
bz, err := cs.ParsedHeader.GetChainHeaderBytes()
if err != nil {
panic(err)
}
return bz
}
func (cs IBFT2State) SealingHeaderRLP() []byte {
bz, err := cs.ParsedHeader.GetSealingHeaderBytes()
if err != nil {
panic(err)
}
return bz
}
func (cs IBFT2State) GetCommitSeals() [][]byte {
return cs.CommitSeals
}
func (cs IBFT2State) Validators() [][]byte {
var addrs [][]byte
for _, val := range cs.ParsedHeader.Validators {
addrs = append(addrs, val.Bytes())
}
return addrs
}