-
Notifications
You must be signed in to change notification settings - Fork 0
/
rollup.go
130 lines (107 loc) Β· 4.14 KB
/
rollup.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
package main
import (
"context"
"encoding/hex"
"fmt"
"log"
"math/big"
wrapper "github.com/celestiaorg/blobstream-contracts/v4/wrappers/Blobstream.sol"
"github.com/celestiaorg/celestia-app/pkg/square"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
ethcmn "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/tendermint/tendermint/crypto/merkle"
"github.com/tendermint/tendermint/rpc/client/http"
)
const (
txHash = "4B122452FA679F15B458271512816B933803D5870919F67969B4D62221D70346"
blobIndex = 0
rpcEndpoint = "tcp://consensus.lunaroasis.net:26657"
evmRPC = "https://eth-goerli.public.blastapi.io"
contractAddr = "0x046120E6c6C48C05627FB369756F5f44858950a5"
dataCommitmentStartBlock = 105001
dataCommitmentEndBlock = 106001
dataCommitmentNonce = 106
)
func main() {
log.Println("π± Starting the verification process...")
if err := verify(); err != nil {
log.Fatalf("β Verification process failed: %v", err)
}
log.Println("β
Verification process completed successfully.")
}
func verify() error {
log.Println("π Decoding transaction hash...")
txHashBz, err := hex.DecodeString(txHash)
if err != nil {
return fmt.Errorf("failed to decode transaction hash: %w", err)
}
log.Println("π Establishing connection to Celestia...")
trpc, err := http.New(rpcEndpoint, "/websocket")
if err != nil {
return fmt.Errorf("failed to connect to Celestia: %w", err)
}
defer trpc.Stop()
ctx := context.Background()
log.Println("π¦ Fetching transaction with decoded hash from Celestia...")
tx, err := trpc.Tx(ctx, txHashBz, true)
if err != nil {
return fmt.Errorf("failed to fetch transaction: %w", err)
}
log.Println("π¦ Fetching block from Celestia...")
block, err := trpc.Block(ctx, &tx.Height)
if err != nil {
return fmt.Errorf("failed to fetch block: %w", err)
}
// Calculate the range of shares that the blob toccupied in the block
blobShareRange, err := square.BlobShareRange(block.Block.Txs.ToSliceOfBytes(), int(tx.Index), int(blobIndex), block.Block.Version.App)
if err != nil {
return fmt.Errorf("failed to get blob share range: %w", err)
}
shareProofs, err := trpc.ProveShares(ctx, uint64(tx.Height), uint64(blobShareRange.Start), uint64(blobShareRange.End))
if err != nil {
return fmt.Errorf("failed to get share proofs: %w", err)
}
log.Println("π Verifying share proofs...")
if !shareProofs.VerifyProof() {
return fmt.Errorf("failed to verify share proofs: %w", err)
}
log.Println("π Generating data root inclusion proof...")
dcProof, err := trpc.DataRootInclusionProof(ctx, uint64(tx.Height), dataCommitmentStartBlock, dataCommitmentEndBlock)
if err != nil {
return fmt.Errorf("failed to generate data root inclusion proof: %w", err)
}
log.Println("π Establishing connection to Ethereum client...")
ethClient, err := ethclient.Dial(evmRPC)
if err != nil {
return fmt.Errorf("failed to connect to Ethereum client: %w", err)
}
defer ethClient.Close()
log.Println("π¦ Fetching BlobstreamX contract...")
contractAddress := ethcmn.HexToAddress(contractAddr)
blobstreamWrapper, err := wrapper.NewWrappers(contractAddress, ethClient)
if err != nil {
return fmt.Errorf("failed to fetch BlobstreamX contract: %w", err)
}
log.Println("π Verifying data root inclusion on BlobstreamX contract...")
VerifyDataRootInclusion(blobstreamWrapper, tx.Height, dataCommitmentNonce, block.Block.DataHash, dcProof.Proof)
return nil
}
func VerifyDataRootInclusion(blobstreamWrapper *wrapper.Wrappers, height int64, nonce int, dataRoot []byte,
proof merkle.Proof) (bool, error) {
tuple := wrapper.DataRootTuple{
Height: big.NewInt(height),
DataRoot: *(*[32]byte)(dataRoot),
}
sideNodes := make([][32]byte, len(proof.Aunts))
for i, aunt := range proof.Aunts {
sideNodes[i] = *(*[32]byte)(aunt)
}
wrappedProof := wrapper.BinaryMerkleProof{
SideNodes: sideNodes,
Key: big.NewInt(proof.Index),
NumLeaves: big.NewInt(proof.Total),
}
valid, err := blobstreamWrapper.VerifyAttestation(&bind.CallOpts{}, big.NewInt(int64(nonce)), tuple, wrappedProof)
return valid, err
}