-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
encoded_signal_proof.go
126 lines (106 loc) · 3 KB
/
encoded_signal_proof.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
package proof
import (
"context"
"math/big"
"log/slog"
"github.com/taikoxyz/taiko-mono/packages/relayer"
"github.com/taikoxyz/taiko-mono/packages/relayer/pkg/encoding"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
)
type HopParams struct {
ChainID *big.Int
SignalServiceAddress common.Address
SignalService relayer.SignalService
Key [32]byte
Blocker blocker
Caller relayer.Caller
BlockNumber uint64
}
func (p *Prover) EncodedSignalProofWithHops(
ctx context.Context,
hopParams []HopParams,
) ([]byte, error) {
return p.abiEncodeSignalProofWithHops(ctx,
hopParams,
)
}
func (p *Prover) abiEncodeSignalProofWithHops(ctx context.Context,
hopParams []HopParams,
) ([]byte, error) {
hopProofs := []encoding.HopProof{}
for _, hop := range hopParams {
slog.Info("generating hop proof")
block, err := hop.Blocker.BlockByNumber(
ctx,
new(big.Int).SetUint64(hop.BlockNumber),
)
if err != nil {
return nil, errors.Wrap(err, "p.blockHeader")
}
ethProof, err := p.getProof(
ctx,
hop.Caller,
hop.SignalServiceAddress,
common.Bytes2Hex(hop.Key[:]),
int64(hop.BlockNumber),
)
if err != nil {
return nil, errors.Wrap(err, "hop p.getEncodedMerkleProof")
}
slog.Info("generated hop proof",
"chainID", hop.ChainID.Uint64(),
"blockID", block.NumberU64(),
"rootHash", block.Root(),
)
hopProofs = append(hopProofs, encoding.HopProof{
BlockID: block.NumberU64(),
ChainID: hop.ChainID.Uint64(),
RootHash: block.Root(),
CacheOption: encoding.CACHE_NOTHING,
AccountProof: ethProof.AccountProof,
StorageProof: ethProof.StorageProof[0].Proof,
},
)
}
encodedSignalProof, err := encoding.EncodeHopProofs(hopProofs)
if err != nil {
return nil, errors.Wrap(err, "enoding.EncodeHopProofs")
}
return encodedSignalProof, nil
}
// getProof rlp and abi encodes a proof for SignalService,
// where `proof` is an rlp and abi encoded (bytes, bytes) consisting of storageProof.Proofs[0]
// response from `eth_getProof`, and returns the storageHash to be used as the signalRoot.
func (p *Prover) getProof(
ctx context.Context,
c relayer.Caller,
signalServiceAddress common.Address,
key string,
blockNumber int64,
) (*StorageProof, error) {
var ethProof StorageProof
slog.Info("getting proof",
"signalServiceAddress", signalServiceAddress.Hex(),
"key", key,
"blockNum", blockNumber,
)
err := c.CallContext(ctx,
ðProof,
"eth_getProof",
signalServiceAddress,
[]string{key},
hexutil.EncodeBig(new(big.Int).SetInt64(blockNumber)),
)
if err != nil {
return nil, errors.Wrap(err, "c.CallContext")
}
slog.Info("proof generated",
"value", common.Bytes2Hex(ethProof.StorageProof[0].Value),
)
if new(big.Int).SetBytes(ethProof.StorageProof[0].Value).Int64() == int64(0) {
return nil, errors.New("proof will not be valid, expected storageProof to not be 0 but was not")
}
return ðProof, nil
}