Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
893bf27b
Commit
893bf27b
authored
Apr 16, 2025
by
vicotor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update for withdrawal
parent
a5ab73f9
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
165 additions
and
299 deletions
+165
-299
engine.go
engine/engine.go
+18
-22
chainReader.go
exchain/chaindb/chainReader.go
+12
-21
chaindb.go
exchain/chaindb/chaindb.go
+12
-21
checkpoint.go
exchain/checkpoint.go
+9
-9
server.go
exchain/exchainapi/server.go
+2
-2
client.go
exchain/exchainclient/client.go
+1
-1
node.pb.go
exchain/protocol/gen/go/node/v1/node.pb.go
+3
-3
node.proto
exchain/protocol/proto/node/v1/node.proto
+1
-1
helper.go
exchain/wdt/helper.go
+0
-63
wdt.go
exchain/wdt/wdt.go
+44
-132
tx.go
exchain/wrapper/tx.go
+32
-16
tx_test.go
exchain/wrapper/tx_test.go
+23
-0
api.go
op-node/node/api.go
+2
-2
system.go
op-node/rollup/interop/managed/system.go
+3
-3
operator.go
op-proposer/proposer/operator.go
+2
-2
withdrawal_proof.go
op-service/eth/withdrawal_proof.go
+1
-1
No files found.
engine/engine.go
View file @
893bf27b
...
@@ -39,52 +39,50 @@ func (e *ExChainAPI) FetchReceipts(ctx context.Context, blockHash common.Hash) (
...
@@ -39,52 +39,50 @@ func (e *ExChainAPI) FetchReceipts(ctx context.Context, blockHash common.Hash) (
return
nil
,
nil
,
errors
.
New
(
"FetchReceipts is not implemented in exchain currently"
)
return
nil
,
nil
,
errors
.
New
(
"FetchReceipts is not implemented in exchain currently"
)
}
}
func
(
e
*
ExChainAPI
)
GetWDTRoot
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
(
common
.
Hash
,
error
)
{
func
(
e
*
ExChainAPI
)
GetWDTRoot
(
ctx
context
.
Context
,
height
uint64
)
(
common
.
Hash
,
error
)
{
block
:=
e
.
chain
.
BlockByHash
(
blockHash
)
tree
,
err
:=
e
.
chain
.
GetWDT
(
height
)
if
block
==
nil
{
return
common
.
Hash
{},
errors
.
New
(
"block not found in exchain"
)
}
tree
,
err
:=
e
.
chain
.
GetWDT
(
*
uint256
.
NewInt
(
block
.
Header
.
Height
))
if
err
!=
nil
{
if
err
!=
nil
{
return
common
.
Hash
{},
err
return
common
.
Hash
{},
err
}
}
return
common
.
BytesToHash
(
tree
.
Root
()
),
nil
return
tree
.
Root
(
),
nil
}
}
func
(
e
*
ExChainAPI
)
WithdrawalProof
(
ctx
context
.
Context
,
txHash
common
.
Hash
)
(
*
eth
.
WithdrawalProof
,
error
)
{
func
(
e
*
ExChainAPI
)
WithdrawalProof
(
ctx
context
.
Context
,
txHash
common
.
Hash
)
(
*
eth
.
WithdrawalProof
,
error
)
{
block
:=
e
.
chain
.
BlockByHash
(
txHash
)
if
block
==
nil
{
return
nil
,
errors
.
New
(
"block not found in exchain"
)
}
wblk
:=
wrapper
.
NewBlkWrapper
(
block
)
var
res
=
&
eth
.
WithdrawalProof
{}
var
res
=
&
eth
.
WithdrawalProof
{}
tx
,
_
:=
e
.
chain
.
GetTransaction
(
txHash
)
tx
,
_
:=
e
.
chain
.
GetTransaction
(
txHash
)
if
tx
==
nil
{
return
nil
,
errors
.
New
(
"transaction not found"
)
}
wtx
:=
tx
.
GetWithdrawTx
()
wtx
:=
tx
.
GetWithdrawTx
()
if
wtx
==
nil
{
if
wtx
==
nil
{
return
nil
,
errors
.
New
(
"transaction is not withdrawal tx"
)
return
nil
,
errors
.
New
(
"transaction is not withdrawal tx"
)
}
}
receipt
:=
e
.
chain
.
GetReceipt
(
txHash
)
receipt
:=
e
.
chain
.
GetReceipt
(
txHash
)
if
receipt
==
nil
{
if
receipt
==
nil
{
return
nil
,
errors
.
New
(
"not found tx receipt"
)
return
nil
,
errors
.
New
(
"not found tx receipt"
)
}
}
tree
,
err
:=
e
.
chain
.
GetWDT
(
*
uint256
.
NewInt
(
receipt
.
BlockHeight
)
)
tree
,
err
:=
e
.
chain
.
GetWDT
(
receipt
.
BlockHeight
)
if
err
!=
nil
{
if
err
!=
nil
{
// generate wdt for block failed.
return
nil
,
err
return
nil
,
err
}
}
item
:=
wrapper
.
NewTxWrapper
(
tx
)
.
WithdrawalHash
()
item
:=
wrapper
.
NewTxWrapper
(
tx
)
.
WithdrawalHash
()
proof
,
err
:=
tree
.
Merkle
Proof
(
item
.
Bytes
())
proof
,
err
:=
tree
.
Proof
(
item
.
Bytes
())
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
errors
.
New
(
fmt
.
Sprintf
(
"failed to get proof (%s)"
,
err
.
Error
()))
return
nil
,
errors
.
New
(
fmt
.
Sprintf
(
"failed to get proof (%s)"
,
err
.
Error
()))
}
}
res
.
Proof
=
make
([]
eth
.
Bytes32
,
len
(
proof
))
res
.
Proof
=
make
([]
string
,
len
(
proof
))
for
i
,
p
:=
range
proof
{
for
i
,
p
:=
range
proof
{
copy
(
res
.
Proof
[
i
][
:
],
p
[
:
])
res
.
Proof
[
i
]
=
p
}
}
res
.
Value
=
new
(
big
.
Int
)
.
SetBytes
(
wtx
.
Amount
)
res
.
Value
=
new
(
big
.
Int
)
.
SetBytes
(
wtx
.
Amount
)
res
.
User
=
common
.
BytesToAddress
(
wtx
.
User
)
res
.
User
=
common
.
BytesToAddress
(
wtx
.
User
)
res
.
Coin
=
[]
byte
(
wtx
.
Coin
)
res
.
Coin
=
[]
byte
(
wtx
.
Coin
)
oo
,
err
:=
e
.
OutputV0AtBlock
(
ctx
,
wblk
.
Hash
()
)
oo
,
err
:=
e
.
OutputV0AtBlock
(
ctx
,
receipt
.
BlockHeight
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
WithField
(
"error"
,
err
)
.
Error
(
"failed to get output for withdrawal proof"
)
log
.
WithField
(
"error"
,
err
)
.
Error
(
"failed to get output for withdrawal proof"
)
return
nil
,
err
return
nil
,
err
...
@@ -111,22 +109,20 @@ func (e *ExChainAPI) WithdrawalTxs(ctx context.Context, blockNum uint64) ([]comm
...
@@ -111,22 +109,20 @@ func (e *ExChainAPI) WithdrawalTxs(ctx context.Context, blockNum uint64) ([]comm
return
txHashes
,
nil
return
txHashes
,
nil
}
}
func
(
e
*
ExChainAPI
)
OutputV0AtBlock
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
(
*
eth
.
OutputV0
,
error
)
{
func
(
e
*
ExChainAPI
)
OutputV0AtBlock
(
ctx
context
.
Context
,
number
uint64
)
(
*
eth
.
OutputV0
,
error
)
{
blk
:=
e
.
chain
.
BlockByHash
(
blockHash
)
blk
:=
e
.
chain
.
GetBlock
(
uint256
.
NewInt
(
number
)
)
if
blk
==
nil
{
if
blk
==
nil
{
return
nil
,
errors
.
New
(
"block not found in exchain"
)
return
nil
,
errors
.
New
(
"block not found in exchain"
)
}
}
wblk
:=
wrapper
.
NewBlkWrapper
(
blk
)
wblk
:=
wrapper
.
NewBlkWrapper
(
blk
)
root
:=
eth
.
Bytes32
{}
root
:=
eth
.
Bytes32
{}
wdtroot
,
err
:=
e
.
GetWDTRoot
(
ctx
,
blockHash
)
wdtroot
,
err
:=
e
.
GetWDTRoot
(
ctx
,
number
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
WithField
(
"error"
,
err
)
.
Error
(
"failed to get wdt root"
)
log
.
WithField
(
"error"
,
err
)
.
Error
(
"failed to get wdt root"
)
return
nil
,
err
return
nil
,
err
}
}
storageRoot
:=
eth
.
Bytes32
(
wdtroot
[
:
])
storageRoot
:=
eth
.
Bytes32
(
wdtroot
[
:
])
// todo: vicotor implement this.
copy
(
root
[
:
],
wblk
.
Header
()
.
AppRoot
)
copy
(
root
[
:
],
wblk
.
Header
()
.
AppRoot
)
return
&
eth
.
OutputV0
{
return
&
eth
.
OutputV0
{
...
...
exchain/chaindb/chainReader.go
View file @
893bf27b
...
@@ -3,7 +3,6 @@ package chaindb
...
@@ -3,7 +3,6 @@ package chaindb
import
(
import
(
"errors"
"errors"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/log"
"github.com/exchain/go-exchain/exchain"
"github.com/exchain/go-exchain/exchain"
nebulav1
"github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1"
nebulav1
"github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1"
...
@@ -26,7 +25,7 @@ type ChainReader interface {
...
@@ -26,7 +25,7 @@ type ChainReader interface {
BlockByHash
(
hash
common
.
Hash
)
*
nebulav1
.
Block
BlockByHash
(
hash
common
.
Hash
)
*
nebulav1
.
Block
GetTransaction
(
hash
common
.
Hash
)
(
*
nebulav1
.
Transaction
,
error
)
GetTransaction
(
hash
common
.
Hash
)
(
*
nebulav1
.
Transaction
,
error
)
GetReceipt
(
hash
common
.
Hash
)
*
nebulav1
.
TransactionReceipt
GetReceipt
(
hash
common
.
Hash
)
*
nebulav1
.
TransactionReceipt
GetWDT
(
number
uint
256
.
Int
)
(
*
wdt
.
MerkleTree
,
error
)
GetWDT
(
number
uint
64
)
(
*
wdt
.
WDT
,
error
)
}
}
func
NewChainReader
(
log
log
.
Logger
,
database
metadb
.
Database
)
ChainReader
{
func
NewChainReader
(
log
log
.
Logger
,
database
metadb
.
Database
)
ChainReader
{
...
@@ -196,14 +195,14 @@ func (m *chainReader) GetBlockReceipts(num *uint256.Int) *nebulav1.TransactionRe
...
@@ -196,14 +195,14 @@ func (m *chainReader) GetBlockReceipts(num *uint256.Int) *nebulav1.TransactionRe
return
m
.
getBlockReceipts
(
num
)
return
m
.
getBlockReceipts
(
num
)
}
}
func
(
m
*
chainReader
)
GetWDT
(
number
uint
256
.
Int
)
(
*
wdt
.
MerkleTree
,
error
)
{
func
(
m
*
chainReader
)
GetWDT
(
number
uint
64
)
(
*
wdt
.
WDT
,
error
)
{
cp
:=
exchain
.
ToCheckpoint
(
number
)
cp
:=
exchain
.
ToCheckpoint
(
number
)
latest
:=
m
.
CurrentHeight
()
latest
:=
m
.
CurrentHeight
()
if
latest
.
Cmp
(
cp
.
End
())
<
0
{
if
latest
.
Uint64
()
<
number
{
return
nil
,
errors
.
New
(
"checkpoint not ready"
)
return
nil
,
errors
.
New
(
"checkpoint not ready"
)
}
}
if
t
,
_
:=
m
.
wdtCache
.
Get
(
cp
);
t
!=
nil
{
if
t
,
_
:=
m
.
wdtCache
.
Get
(
cp
);
t
!=
nil
{
return
t
.
(
*
wdt
.
MerkleTree
),
nil
return
t
.
(
*
wdt
.
WDT
),
nil
}
}
nt
,
err
:=
m
.
generateWDT
(
cp
)
nt
,
err
:=
m
.
generateWDT
(
cp
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -213,11 +212,12 @@ func (m *chainReader) GetWDT(number uint256.Int) (*wdt.MerkleTree, error) {
...
@@ -213,11 +212,12 @@ func (m *chainReader) GetWDT(number uint256.Int) (*wdt.MerkleTree, error) {
return
nt
,
nil
return
nt
,
nil
}
}
func
(
m
*
chainReader
)
generateWDT
(
cp
exchain
.
Checkpoint
)
(
*
wdt
.
MerkleTree
,
error
)
{
func
(
m
*
chainReader
)
generateWDT
(
cp
exchain
.
Checkpoint
)
(
*
wdt
.
WDT
,
error
)
{
withdrawalTxs
:=
&
nebulav1
.
TransactionList
{
withdrawalTxs
:=
&
nebulav1
.
TransactionList
{
Txs
:
make
([]
*
nebulav1
.
Transaction
,
0
),
Txs
:
make
([]
*
nebulav1
.
Transaction
,
0
),
}
}
for
i
:=
cp
.
Start
()
.
Uint64
();
i
<=
cp
.
End
()
.
Uint64
();
i
++
{
trie
:=
wdt
.
NewWdt
()
for
i
:=
cp
.
Start
();
i
<=
cp
.
End
();
i
++
{
blk
:=
m
.
GetBlock
(
uint256
.
NewInt
(
i
))
blk
:=
m
.
GetBlock
(
uint256
.
NewInt
(
i
))
if
blk
==
nil
{
if
blk
==
nil
{
return
nil
,
errors
.
New
(
"block not found in exchain"
)
return
nil
,
errors
.
New
(
"block not found in exchain"
)
...
@@ -225,22 +225,13 @@ func (m *chainReader) generateWDT(cp exchain.Checkpoint) (*wdt.MerkleTree, error
...
@@ -225,22 +225,13 @@ func (m *chainReader) generateWDT(cp exchain.Checkpoint) (*wdt.MerkleTree, error
wblk
:=
wrapper
.
NewBlkWrapper
(
blk
)
wblk
:=
wrapper
.
NewBlkWrapper
(
blk
)
withdrawalTxs
.
Txs
=
append
(
withdrawalTxs
.
Txs
,
wblk
.
FilterTransactions
(
wrapper
.
TxTypeFilter
(
nebulav1
.
TxType_WithdrawTx
))
...
)
withdrawalTxs
.
Txs
=
append
(
withdrawalTxs
.
Txs
,
wblk
.
FilterTransactions
(
wrapper
.
TxTypeFilter
(
nebulav1
.
TxType_WithdrawTx
))
...
)
}
}
leaves
:=
make
([][]
byte
,
len
(
withdrawalTxs
.
Txs
))
for
_
,
tx
:=
range
withdrawalTxs
.
Txs
{
for
_
,
tx
:=
range
withdrawalTxs
.
Txs
{
content
:=
tx
.
GetWithdrawTx
()
if
err
:=
trie
.
AddTx
(
tx
);
err
!=
nil
{
data
:=
make
([]
byte
,
0
)
return
nil
,
err
}
data
=
append
(
data
,
content
.
User
...
)
data
=
append
(
data
,
content
.
Coin
...
)
data
=
append
(
data
,
content
.
Amount
...
)
leaves
=
append
(
leaves
,
crypto
.
Keccak256Hash
(
data
)
.
Bytes
())
}
tree
,
err
:=
wdt
.
GenerateTreeFromHashedItems
(
leaves
)
if
err
!=
nil
{
m
.
log
.
Error
(
"failed to generate wdt tree"
,
"err"
,
err
)
return
nil
,
err
}
}
return
tree
,
nil
return
trie
,
nil
}
}
func
(
m
*
chainReader
)
blockNumberByHash
(
hash
common
.
Hash
)
*
uint256
.
Int
{
func
(
m
*
chainReader
)
blockNumberByHash
(
hash
common
.
Hash
)
*
uint256
.
Int
{
...
...
exchain/chaindb/chaindb.go
View file @
893bf27b
...
@@ -4,7 +4,6 @@ import (
...
@@ -4,7 +4,6 @@ import (
"errors"
"errors"
"fmt"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/log"
"github.com/exchain/go-exchain/exchain"
"github.com/exchain/go-exchain/exchain"
...
@@ -41,7 +40,7 @@ type ChainDB interface {
...
@@ -41,7 +40,7 @@ type ChainDB interface {
SubscribeChainEvent
(
ch
chan
<-
exchain
.
ChainEvent
)
event
.
Subscription
SubscribeChainEvent
(
ch
chan
<-
exchain
.
ChainEvent
)
event
.
Subscription
EmitChain
(
block
*
nebulav1
.
Block
,
hash
common
.
Hash
)
EmitChain
(
block
*
nebulav1
.
Block
,
hash
common
.
Hash
)
ResetHeight
(
*
uint256
.
Int
,
bool
)
error
ResetHeight
(
*
uint256
.
Int
,
bool
)
error
GetWDT
(
number
uint
256
.
Int
)
(
*
wdt
.
MerkleTree
,
error
)
GetWDT
(
number
uint
64
)
(
*
wdt
.
WDT
,
error
)
}
}
var
(
var
(
...
@@ -123,14 +122,14 @@ func (m *chaindb) ChainId() (*uint256.Int, error) {
...
@@ -123,14 +122,14 @@ func (m *chaindb) ChainId() (*uint256.Int, error) {
}
}
}
}
func
(
m
*
chaindb
)
GetWDT
(
number
uint
256
.
Int
)
(
*
wdt
.
MerkleTree
,
error
)
{
func
(
m
*
chaindb
)
GetWDT
(
number
uint
64
)
(
*
wdt
.
WDT
,
error
)
{
cp
:=
exchain
.
ToCheckpoint
(
number
)
cp
:=
exchain
.
ToCheckpoint
(
number
)
latest
:=
m
.
CurrentHeight
()
latest
:=
m
.
CurrentHeight
()
if
latest
.
Cmp
(
cp
.
End
())
<
0
{
if
latest
.
Uint64
()
<
cp
.
End
()
{
return
nil
,
errors
.
New
(
"checkpoint not ready"
)
return
nil
,
errors
.
New
(
"checkpoint not ready"
)
}
}
if
t
,
_
:=
m
.
wdtCache
.
Get
(
cp
);
t
!=
nil
{
if
t
,
_
:=
m
.
wdtCache
.
Get
(
cp
);
t
!=
nil
{
return
t
.
(
*
wdt
.
MerkleTree
),
nil
return
t
.
(
*
wdt
.
WDT
),
nil
}
}
nt
,
err
:=
m
.
generateWDT
(
cp
)
nt
,
err
:=
m
.
generateWDT
(
cp
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -140,11 +139,12 @@ func (m *chaindb) GetWDT(number uint256.Int) (*wdt.MerkleTree, error) {
...
@@ -140,11 +139,12 @@ func (m *chaindb) GetWDT(number uint256.Int) (*wdt.MerkleTree, error) {
return
nt
,
nil
return
nt
,
nil
}
}
func
(
m
*
chaindb
)
generateWDT
(
cp
exchain
.
Checkpoint
)
(
*
wdt
.
MerkleTree
,
error
)
{
func
(
m
*
chaindb
)
generateWDT
(
cp
exchain
.
Checkpoint
)
(
*
wdt
.
WDT
,
error
)
{
withdrawalTxs
:=
&
nebulav1
.
TransactionList
{
withdrawalTxs
:=
&
nebulav1
.
TransactionList
{
Txs
:
make
([]
*
nebulav1
.
Transaction
,
0
),
Txs
:
make
([]
*
nebulav1
.
Transaction
,
0
),
}
}
for
i
:=
cp
.
Start
()
.
Uint64
();
i
<=
cp
.
End
()
.
Uint64
();
i
++
{
trie
:=
wdt
.
NewWdt
()
for
i
:=
cp
.
Start
();
i
<=
cp
.
End
();
i
++
{
blk
:=
m
.
GetBlock
(
uint256
.
NewInt
(
i
))
blk
:=
m
.
GetBlock
(
uint256
.
NewInt
(
i
))
if
blk
==
nil
{
if
blk
==
nil
{
return
nil
,
errors
.
New
(
"block not found in exchain"
)
return
nil
,
errors
.
New
(
"block not found in exchain"
)
...
@@ -152,22 +152,13 @@ func (m *chaindb) generateWDT(cp exchain.Checkpoint) (*wdt.MerkleTree, error) {
...
@@ -152,22 +152,13 @@ func (m *chaindb) generateWDT(cp exchain.Checkpoint) (*wdt.MerkleTree, error) {
wblk
:=
wrapper
.
NewBlkWrapper
(
blk
)
wblk
:=
wrapper
.
NewBlkWrapper
(
blk
)
withdrawalTxs
.
Txs
=
append
(
withdrawalTxs
.
Txs
,
wblk
.
FilterTransactions
(
wrapper
.
TxTypeFilter
(
nebulav1
.
TxType_WithdrawTx
))
...
)
withdrawalTxs
.
Txs
=
append
(
withdrawalTxs
.
Txs
,
wblk
.
FilterTransactions
(
wrapper
.
TxTypeFilter
(
nebulav1
.
TxType_WithdrawTx
))
...
)
}
}
leaves
:=
make
([][]
byte
,
len
(
withdrawalTxs
.
Txs
))
for
_
,
tx
:=
range
withdrawalTxs
.
Txs
{
for
_
,
tx
:=
range
withdrawalTxs
.
Txs
{
content
:=
tx
.
GetWithdrawTx
()
if
err
:=
trie
.
AddTx
(
tx
);
err
!=
nil
{
data
:=
make
([]
byte
,
0
)
return
nil
,
err
}
data
=
append
(
data
,
content
.
User
...
)
data
=
append
(
data
,
content
.
Coin
...
)
data
=
append
(
data
,
content
.
Amount
...
)
leaves
=
append
(
leaves
,
crypto
.
Keccak256Hash
(
data
)
.
Bytes
())
}
tree
,
err
:=
wdt
.
GenerateTreeFromHashedItems
(
leaves
)
if
err
!=
nil
{
m
.
log
.
Error
(
"failed to generate wdt tree"
,
"err"
,
err
)
return
nil
,
err
}
}
return
tree
,
nil
return
trie
,
nil
}
}
func
(
m
*
chaindb
)
SaveChainId
(
chainid
*
uint256
.
Int
)
error
{
func
(
m
*
chaindb
)
SaveChainId
(
chainid
*
uint256
.
Int
)
error
{
...
...
exchain/checkpoint.go
View file @
893bf27b
...
@@ -3,7 +3,7 @@ package exchain
...
@@ -3,7 +3,7 @@ package exchain
import
"github.com/holiman/uint256"
import
"github.com/holiman/uint256"
const
(
const
(
ChainCheckpointInterval
=
120
// 1 checkpoint every 120 blocks, from 1 to 120, 121 to 240, etc.
ChainCheckpointInterval
=
uint64
(
120
)
// 1 checkpoint every 120 blocks, from 1 to 120, 121 to 240, etc.
)
)
...
@@ -13,22 +13,22 @@ var (
...
@@ -13,22 +13,22 @@ var (
type
Checkpoint
uint64
type
Checkpoint
uint64
func
(
c
Checkpoint
)
Start
()
*
uint256
.
Int
{
func
(
c
Checkpoint
)
Start
()
uint64
{
// start = interval * cp + 1
// start = interval * cp + 1
start
:=
new
(
uint256
.
Int
)
.
Add
(
big1
,
new
(
uint256
.
Int
)
.
Mul
(
uint256
.
NewInt
(
uint64
(
c
)),
uint256
.
NewInt
(
ChainCheckpointInterval
)))
start
:=
ChainCheckpointInterval
*
uint64
(
c
)
+
1
return
start
return
start
}
}
func
(
c
Checkpoint
)
End
()
*
uint256
.
Int
{
func
(
c
Checkpoint
)
End
()
uint64
{
// end = interval * (cp + 1)
// end = interval * (cp + 1)
end
:=
new
(
uint256
.
Int
)
.
Mul
(
new
(
uint256
.
Int
)
.
Add
(
big1
,
uint256
.
NewInt
(
uint64
(
c
))),
uint256
.
NewInt
(
ChainCheckpointInterval
)
)
end
:=
ChainCheckpointInterval
*
(
uint64
(
c
)
+
1
)
return
end
return
end
}
}
func
ToCheckpoint
(
number
uint
256
.
Int
)
Checkpoint
{
func
ToCheckpoint
(
number
uint
64
)
Checkpoint
{
if
number
.
IsZero
()
{
if
number
==
0
{
return
0
return
0
}
}
cp
:=
new
(
uint256
.
Int
)
.
Div
(
new
(
uint256
.
Int
)
.
SubUint64
(
&
number
,
1
),
uint256
.
NewInt
(
ChainCheckpointInterval
))
cp
:=
(
number
-
1
)
/
ChainCheckpointInterval
return
Checkpoint
(
cp
.
Uint64
()
)
return
Checkpoint
(
cp
)
}
}
exchain/exchainapi/server.go
View file @
893bf27b
...
@@ -111,12 +111,12 @@ func (s *server) GetWithdrawalProof(ctx context.Context, request *nodev1.Withdra
...
@@ -111,12 +111,12 @@ func (s *server) GetWithdrawalProof(ctx context.Context, request *nodev1.Withdra
if
receipt
==
nil
{
if
receipt
==
nil
{
return
nil
,
errors
.
New
(
"not found tx receipt"
)
return
nil
,
errors
.
New
(
"not found tx receipt"
)
}
}
tree
,
err
:=
s
.
chain
.
GetWDT
(
*
uint256
.
NewInt
(
receipt
.
BlockHeight
)
)
tree
,
err
:=
s
.
chain
.
GetWDT
(
receipt
.
BlockHeight
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
item
:=
wrapper
.
NewTxWrapper
(
tx
)
.
WithdrawalHash
()
item
:=
wrapper
.
NewTxWrapper
(
tx
)
.
WithdrawalHash
()
proof
,
err
:=
tree
.
Merkle
Proof
(
item
.
Bytes
())
proof
,
err
:=
tree
.
Proof
(
item
.
Bytes
())
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
errors
.
New
(
fmt
.
Sprintf
(
"failed to get proof (%s)"
,
err
.
Error
()))
return
nil
,
errors
.
New
(
fmt
.
Sprintf
(
"failed to get proof (%s)"
,
err
.
Error
()))
}
}
...
...
exchain/exchainclient/client.go
View file @
893bf27b
...
@@ -38,7 +38,7 @@ func (e *ExClient) BlockByNumber(ctx context.Context, number *big.Int) (*wrapper
...
@@ -38,7 +38,7 @@ func (e *ExClient) BlockByNumber(ctx context.Context, number *big.Int) (*wrapper
return
wrapper
.
NewBlkWrapper
(
res
.
Block
),
nil
return
wrapper
.
NewBlkWrapper
(
res
.
Block
),
nil
}
}
func
(
e
*
ExClient
)
GetWithdrawalProof
(
ctx
context
.
Context
,
param
exchain
.
ExChainWithdrawalParam
)
([]
[]
byte
,
error
)
{
func
(
e
*
ExClient
)
GetWithdrawalProof
(
ctx
context
.
Context
,
param
exchain
.
ExChainWithdrawalParam
)
([]
string
,
error
)
{
req
:=
&
nodev1
.
WithdrawalProofRequest
{
req
:=
&
nodev1
.
WithdrawalProofRequest
{
Txhash
:
param
.
TxHash
.
String
(),
Txhash
:
param
.
TxHash
.
String
(),
}
}
...
...
exchain/protocol/gen/go/node/v1/node.pb.go
View file @
893bf27b
...
@@ -914,7 +914,7 @@ type WithdrawalProofResponse struct {
...
@@ -914,7 +914,7 @@ type WithdrawalProofResponse struct {
sizeCache
protoimpl
.
SizeCache
sizeCache
protoimpl
.
SizeCache
unknownFields
protoimpl
.
UnknownFields
unknownFields
protoimpl
.
UnknownFields
Proof
[]
[]
byte
`protobuf:"bytes,1,rep,name=proof,proto3" json:"proof,omitempty"`
Proof
[]
string
`protobuf:"bytes,1,rep,name=proof,proto3" json:"proof,omitempty"`
}
}
func
(
x
*
WithdrawalProofResponse
)
Reset
()
{
func
(
x
*
WithdrawalProofResponse
)
Reset
()
{
...
@@ -949,7 +949,7 @@ func (*WithdrawalProofResponse) Descriptor() ([]byte, []int) {
...
@@ -949,7 +949,7 @@ func (*WithdrawalProofResponse) Descriptor() ([]byte, []int) {
return
file_node_v1_node_proto_rawDescGZIP
(),
[]
int
{
19
}
return
file_node_v1_node_proto_rawDescGZIP
(),
[]
int
{
19
}
}
}
func
(
x
*
WithdrawalProofResponse
)
GetProof
()
[]
[]
byte
{
func
(
x
*
WithdrawalProofResponse
)
GetProof
()
[]
string
{
if
x
!=
nil
{
if
x
!=
nil
{
return
x
.
Proof
return
x
.
Proof
}
}
...
@@ -1052,7 +1052,7 @@ var file_node_v1_node_proto_rawDesc = []byte{
...
@@ -1052,7 +1052,7 @@ var file_node_v1_node_proto_rawDesc = []byte{
0x68
,
0x18
,
0x01
,
0x20
,
0x01
,
0x28
,
0x09
,
0x52
,
0x06
,
0x74
,
0x78
,
0x68
,
0x61
,
0x73
,
0x68
,
0x22
,
0x68
,
0x18
,
0x01
,
0x20
,
0x01
,
0x28
,
0x09
,
0x52
,
0x06
,
0x74
,
0x78
,
0x68
,
0x61
,
0x73
,
0x68
,
0x22
,
0x2f
,
0x0a
,
0x17
,
0x57
,
0x69
,
0x74
,
0x68
,
0x64
,
0x72
,
0x61
,
0x77
,
0x61
,
0x6c
,
0x50
,
0x72
,
0x6f
,
0x2f
,
0x0a
,
0x17
,
0x57
,
0x69
,
0x74
,
0x68
,
0x64
,
0x72
,
0x61
,
0x77
,
0x61
,
0x6c
,
0x50
,
0x72
,
0x6f
,
0x6f
,
0x66
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x12
,
0x14
,
0x0a
,
0x05
,
0x70
,
0x72
,
0x6f
,
0x66
,
0x52
,
0x65
,
0x73
,
0x70
,
0x6f
,
0x6e
,
0x73
,
0x65
,
0x12
,
0x14
,
0x0a
,
0x05
,
0x70
,
0x72
,
0x6f
,
0x6f
,
0x66
,
0x18
,
0x01
,
0x20
,
0x03
,
0x28
,
0x0
c
,
0x52
,
0x05
,
0x70
,
0x72
,
0x6f
,
0x6f
,
0x66
,
0x6f
,
0x6f
,
0x66
,
0x18
,
0x01
,
0x20
,
0x03
,
0x28
,
0x0
9
,
0x52
,
0x05
,
0x70
,
0x72
,
0x6f
,
0x6f
,
0x66
,
0x32
,
0xf6
,
0x0b
,
0x0a
,
0x04
,
0x4e
,
0x6f
,
0x64
,
0x65
,
0x12
,
0x75
,
0x0a
,
0x0a
,
0x47
,
0x65
,
0x74
,
0x32
,
0xf6
,
0x0b
,
0x0a
,
0x04
,
0x4e
,
0x6f
,
0x64
,
0x65
,
0x12
,
0x75
,
0x0a
,
0x0a
,
0x47
,
0x65
,
0x74
,
0x41
,
0x63
,
0x63
,
0x6f
,
0x75
,
0x6e
,
0x74
,
0x12
,
0x1f
,
0x2e
,
0x65
,
0x78
,
0x63
,
0x68
,
0x61
,
0x69
,
0x41
,
0x63
,
0x63
,
0x6f
,
0x75
,
0x6e
,
0x74
,
0x12
,
0x1f
,
0x2e
,
0x65
,
0x78
,
0x63
,
0x68
,
0x61
,
0x69
,
0x6e
,
0x2e
,
0x6e
,
0x6f
,
0x64
,
0x65
,
0x2e
,
0x76
,
0x31
,
0x2e
,
0x41
,
0x63
,
0x63
,
0x6f
,
0x75
,
0x6e
,
0x6e
,
0x2e
,
0x6e
,
0x6f
,
0x64
,
0x65
,
0x2e
,
0x76
,
0x31
,
0x2e
,
0x41
,
0x63
,
0x63
,
0x6f
,
0x75
,
0x6e
,
...
...
exchain/protocol/proto/node/v1/node.proto
View file @
893bf27b
...
@@ -141,5 +141,5 @@ message WithdrawalProofRequest {
...
@@ -141,5 +141,5 @@ message WithdrawalProofRequest {
}
}
message
WithdrawalProofResponse
{
message
WithdrawalProofResponse
{
repeated
bytes
proof
=
1
;
repeated
string
proof
=
1
;
}
}
exchain/wdt/helper.go
deleted
100644 → 0
View file @
a5ab73f9
package
wdt
import
"bytes"
// Sorts2Bytes by contents.
func
Sort2Bytes
(
i
[]
byte
,
j
[]
byte
)
([]
byte
,
[]
byte
)
{
if
lessThanBytes
(
i
,
j
)
{
return
i
,
j
}
else
{
return
j
,
i
}
}
func
lessThanBytes
(
i
[]
byte
,
j
[]
byte
)
bool
{
return
bytes
.
Compare
(
i
,
j
)
<=
0
}
func
safeCopyBytes
(
cp
[]
byte
)
[]
byte
{
if
cp
!=
nil
{
copied
:=
make
([]
byte
,
len
(
cp
))
copy
(
copied
,
cp
)
return
copied
}
return
nil
}
func
copy2dBytes
(
ary
[][]
byte
)
[][]
byte
{
if
ary
!=
nil
{
copied
:=
make
([][]
byte
,
len
(
ary
))
for
i
,
a
:=
range
ary
{
copied
[
i
]
=
safeCopyBytes
(
a
)
}
return
copied
}
return
nil
}
func
padTo
(
b
[]
byte
,
size
int
)
[]
byte
{
if
len
(
b
)
>
size
{
return
b
}
return
append
(
b
,
make
([]
byte
,
size
-
len
(
b
))
...
)
}
// Find the next power of 2 unless n is already a power of 2.
func
nextPowerOf2
(
n
uint64
)
uint64
{
var
count
uint64
=
0
if
isPowerOfTwo
(
n
)
{
return
n
}
for
n
!=
0
{
n
>>=
1
count
+=
1
}
return
1
<<
count
}
func
isPowerOfTwo
(
n
uint64
)
bool
{
return
(
n
&
(
n
-
1
))
==
0
}
exchain/wdt/wdt.go
View file @
893bf27b
package
wdt
package
wdt
import
(
import
(
"
bytes
"
"
github.com/ethereum/go-ethereum/common
"
"
errors
"
"
github.com/ethereum/go-ethereum/common/hexutil
"
"
fmt
"
"
github.com/ethereum/go-ethereum/core/rawdb
"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto"
"math"
"github.com/ethereum/go-ethereum/log"
"sort"
"github.com/ethereum/go-ethereum/trie"
"github.com/ethereum/go-ethereum/triedb"
nebulav1
"github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1"
"github.com/exchain/go-exchain/exchain/wrapper"
)
)
//
WithdrawalTree (wdt) is a merkle tree that stores all the withdrawal information.
//
proofList implements ethdb.KeyValueWriter and collects the proofs as
type
WithdrawalTree
struct
{
// hex-strings for delivery to rpc-caller.
}
type
proofList
[]
string
// MerkleTree implements a general purpose Merkle tree.
func
(
n
*
proofList
)
Put
(
key
[]
byte
,
value
[]
byte
)
error
{
type
MerkleTree
struct
{
*
n
=
append
(
*
n
,
hexutil
.
Encode
(
value
))
branches
[][][]
byte
return
nil
depth
uint64
}
}
func
GenerateTreeFromItems
(
items
[][]
byte
)
(
*
MerkleTree
,
error
)
{
func
(
n
*
proofList
)
Delete
(
key
[]
byte
)
error
{
// Pad all items to 32 bytes.
panic
(
"not supported"
)
leaves
:=
copy2dBytes
(
items
)
for
i
:=
range
leaves
{
leaves
[
i
]
=
hash
(
padTo
(
leaves
[
i
],
32
))
}
return
GenerateTreeFromHashedItems
(
leaves
)
}
}
// GenerateTreeFromItems constructs a Merkle tree from a sequence of byte slices.
type
WDT
struct
{
func
GenerateTreeFromHashedItems
(
items
[][]
byte
)
(
*
MerkleTree
,
error
)
{
id
*
trie
.
ID
if
len
(
items
)
==
0
{
st
*
trie
.
StateTrie
return
nil
,
errors
.
New
(
"no items provided to generate Merkle tree"
)
}
}
// Clone the slice to prevent mutation.
leaves
:=
copy2dBytes
(
items
)
// Sort by byte contents.
sort
.
Slice
(
leaves
,
func
(
i
,
j
int
)
bool
{
return
lessThanBytes
(
leaves
[
i
],
leaves
[
j
])
})
// Even out if uneven.
func
NewWdt
()
*
WDT
{
if
len
(
leaves
)
%
2
==
1
{
virAccount
:=
common
.
HexToAddress
(
"0xffee"
)
duplicate
:=
safeCopyBytes
(
leaves
[
len
(
leaves
)
-
1
])
id
:=
trie
.
StorageTrieID
(
common
.
Hash
{},
crypto
.
Keccak256Hash
(
virAccount
.
Bytes
()),
common
.
Hash
{})
leaves
=
append
(
leaves
,
duplicate
)
trieDB
:=
triedb
.
NewDatabase
(
rawdb
.
NewMemoryDatabase
(),
nil
)
}
st
,
err
:=
trie
.
NewStateTrie
(
id
,
trieDB
)
// Append duplicate nodes until even.
if
err
!=
nil
{
nextPowOfItems
:=
nextPowerOf2
(
uint64
(
len
(
leaves
)))
log
.
Error
(
"failed to create state trie"
,
"err"
,
err
)
for
len
(
leaves
)
<
int
(
nextPowOfItems
)
{
return
nil
leaves
=
append
(
leaves
,
leaves
[
len
(
leaves
)
-
2
],
leaves
[
len
(
leaves
)
-
1
])
}
}
depth
:=
uint64
(
math
.
Log2
(
float64
(
len
(
leaves
))
+
1
))
return
&
WDT
{
layers
:=
make
([][][]
byte
,
depth
+
1
)
id
:
id
,
layers
[
0
]
=
leaves
st
:
st
,
for
i
:=
uint64
(
0
);
i
<
depth
;
i
++
{
var
updatedValues
[][]
byte
for
j
:=
0
;
j
<
len
(
layers
[
i
]);
j
+=
2
{
concat
:=
SortAndHash
(
layers
[
i
][
j
],
layers
[
i
][
j
+
1
])
updatedValues
=
append
(
updatedValues
,
concat
[
:
])
}
layers
[
i
+
1
]
=
updatedValues
}
}
return
&
MerkleTree
{
branches
:
layers
,
depth
:
depth
,
},
nil
}
}
// Items returns the original items passed in when creating the Merkle tree.
func
(
w
*
WDT
)
AddTx
(
tx
*
nebulav1
.
Transaction
)
error
{
func
(
m
*
MerkleTree
)
Items
()
[][]
byte
{
// key is withdrawalHash
return
m
.
branches
[
0
]
// value is []byte("1")
item
:=
wrapper
.
NewTxWrapper
(
tx
)
.
WithdrawalHash
()
addr
:=
common
.
Address
{}
return
w
.
st
.
UpdateStorage
(
addr
,
item
.
Bytes
(),
[]
byte
(
"1"
))
}
}
// Root returns the top-most, Merkle root of the tree.
func
(
w
*
WDT
)
Proof
(
key
[]
byte
)
([]
string
,
error
)
{
func
(
m
*
MerkleTree
)
Root
()
[]
byte
{
var
proof
proofList
return
m
.
branches
[
len
(
m
.
branches
)
-
1
][
0
]
if
err
:=
w
.
st
.
Prove
(
key
,
&
proof
);
err
!=
nil
{
}
return
nil
,
err
// MerkleProof computes a Proof for a leaf from a tree's branches.
func
(
m
*
MerkleTree
)
MerkleProof
(
leaf
[]
byte
)
([][]
byte
,
error
)
{
nextLeaf
:=
leaf
proof
:=
make
([][]
byte
,
m
.
depth
)
for
i
:=
uint64
(
0
);
i
<
m
.
depth
;
i
++
{
leftLeaf
,
rightLeaf
,
err
:=
leafPair
(
m
.
branches
[
i
],
nextLeaf
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"could not find pair: %v"
,
err
)
}
if
bytes
.
Equal
(
leftLeaf
,
nextLeaf
)
{
proof
[
i
]
=
rightLeaf
}
else
{
proof
[
i
]
=
leftLeaf
}
nextLeaf
=
hash
(
leftLeaf
,
rightLeaf
)
}
}
return
proof
,
nil
return
proof
,
nil
}
}
func
(
m
*
MerkleTree
)
MerkleProofOfIndex
(
indexOfLeaf
uint64
)
([][]
byte
,
error
)
{
func
(
w
*
WDT
)
Root
()
common
.
Hash
{
if
int
(
indexOfLeaf
)
>
len
(
m
.
branches
[
0
])
{
// root is the root hash of the trie
return
nil
,
fmt
.
Errorf
(
"could not find index %d, greater than length %d"
,
indexOfLeaf
,
m
.
branches
[
0
])
return
w
.
st
.
Hash
()
}
return
m
.
MerkleProof
(
m
.
branches
[
0
][
indexOfLeaf
])
}
// VerifyMerkleBranch verifies a Merkle branch against a root of a tree.
func
VerifyMerkleBranch
(
root
,
item
[]
byte
,
proof
[][]
byte
)
bool
{
node
:=
safeCopyBytes
(
item
)
for
i
:=
0
;
i
<
len
(
proof
);
i
++
{
if
lessThanBytes
(
node
,
proof
[
i
])
{
node
=
hash
(
node
[
:
],
proof
[
i
])
}
else
{
node
=
hash
(
proof
[
i
],
node
[
:
])
}
}
return
bytes
.
Equal
(
root
,
node
[
:
])
}
func
leafPair
(
leaves
[][]
byte
,
leaf
[]
byte
)
([]
byte
,
[]
byte
,
error
)
{
var
found
bool
var
indexOfLeaf
int
for
i
,
item
:=
range
leaves
{
if
bytes
.
Equal
(
item
,
leaf
)
{
indexOfLeaf
=
i
found
=
true
break
}
}
if
!
found
{
return
nil
,
nil
,
fmt
.
Errorf
(
"could not find leaf %#x"
,
leaf
)
}
var
otherLeaf
[]
byte
// Chcek if the leaf is on the left side.
if
indexOfLeaf
%
2
==
0
{
otherLeaf
=
safeCopyBytes
(
leaves
[
indexOfLeaf
+
1
])
}
else
{
otherLeaf
=
safeCopyBytes
(
leaves
[
indexOfLeaf
-
1
])
}
leftLeaf
,
rightLeaf
:=
Sort2Bytes
(
leaf
,
otherLeaf
)
return
leftLeaf
,
rightLeaf
,
nil
}
// SortAndHash sorts the 2 bytes and keccak256 hashes them.
func
SortAndHash
(
i
[]
byte
,
j
[]
byte
)
[]
byte
{
sorted1
,
sorted2
:=
Sort2Bytes
(
i
,
j
)
return
hash
(
sorted1
,
sorted2
)
}
func
hash
(
data
...
[]
byte
)
[]
byte
{
return
crypto
.
Keccak256
(
data
...
)
}
}
exchain/wrapper/tx.go
View file @
893bf27b
package
wrapper
package
wrapper
import
(
import
(
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp"
"github.com/exchain/go-exchain/exchain"
nebulav1
"github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1"
nebulav1
"github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/proto"
log
"github.com/sirupsen/logrus"
"math/big"
"math/big"
)
)
...
@@ -40,6 +38,32 @@ func (t *TxWrapper) calcHash() common.Hash {
...
@@ -40,6 +38,32 @@ func (t *TxWrapper) calcHash() common.Hash {
}
}
func
withdrawalHash
(
user
common
.
Address
,
coin
string
,
amount
*
big
.
Int
,
txHash
common
.
Hash
)
common
.
Hash
{
uint256Ty
,
_
:=
abi
.
NewType
(
"uint256"
,
""
,
nil
)
bytes32Ty
,
_
:=
abi
.
NewType
(
"bytes32"
,
""
,
nil
)
addressTy
,
_
:=
abi
.
NewType
(
"address"
,
""
,
nil
)
bytesTy
,
_
:=
abi
.
NewType
(
"bytes"
,
""
,
nil
)
arguments
:=
abi
.
Arguments
{
{
Type
:
addressTy
,
},
{
Type
:
bytesTy
,
},
{
Type
:
uint256Ty
,
},
{
Type
:
bytes32Ty
,
},
}
data
,
err
:=
arguments
.
Pack
(
user
,
[]
byte
(
coin
),
amount
,
txHash
)
if
err
!=
nil
{
return
common
.
Hash
{}
}
return
crypto
.
Keccak256Hash
(
data
)
}
func
(
t
*
TxWrapper
)
WithdrawalHash
()
common
.
Hash
{
func
(
t
*
TxWrapper
)
WithdrawalHash
()
common
.
Hash
{
if
t
.
tx
.
TxType
!=
nebulav1
.
TxType_WithdrawTx
{
if
t
.
tx
.
TxType
!=
nebulav1
.
TxType_WithdrawTx
{
return
common
.
Hash
{}
return
common
.
Hash
{}
...
@@ -48,19 +72,11 @@ func (t *TxWrapper) WithdrawalHash() common.Hash {
...
@@ -48,19 +72,11 @@ func (t *TxWrapper) WithdrawalHash() common.Hash {
if
wtx
==
nil
{
if
wtx
==
nil
{
return
common
.
Hash
{}
return
common
.
Hash
{}
}
}
param
:=
exchain
.
ExChainWithdrawalParam
{
user
:=
common
.
BytesToAddress
(
wtx
.
User
)
Value
:
new
(
big
.
Int
)
.
SetBytes
(
wtx
.
Amount
),
coin
:=
string
(
wtx
.
Coin
)
User
:
common
.
BytesToAddress
(
wtx
.
User
),
amount
:=
new
(
big
.
Int
)
.
SetBytes
(
wtx
.
Amount
)
Coin
:
wtx
.
Coin
,
txHash
:=
t
.
Hash
()
}
return
withdrawalHash
(
user
,
coin
,
amount
,
txHash
)
// todo: vicotor check rlp encode?
data
,
err
:=
rlp
.
EncodeToBytes
(
param
)
if
err
!=
nil
{
log
.
WithField
(
"err"
,
err
)
.
Error
(
"rlp encode withdrawal param failed"
)
return
common
.
Hash
{}
}
hash
:=
crypto
.
Keccak256Hash
(
data
)
return
hash
}
}
func
(
t
*
TxWrapper
)
Bytes
()
([]
byte
,
error
)
{
func
(
t
*
TxWrapper
)
Bytes
()
([]
byte
,
error
)
{
...
...
exchain/wrapper/tx_test.go
0 → 100644
View file @
893bf27b
package
wrapper
import
(
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"math/big"
"testing"
)
func
TestWhash
(
t
*
testing
.
T
)
{
user
:=
common
.
HexToAddress
(
"0x000000000000000000000000000000000000dead"
)
coin
:=
"ETH"
value
:=
big
.
NewInt
(
1e18
)
//ethers.keccak256(ethers.toUtf8Bytes("test transaction"));
hash
:=
crypto
.
Keccak256Hash
([]
byte
(
"test transaction"
))
whash
:=
Whash
(
user
,
coin
,
value
,
hash
)
expected
:=
common
.
HexToHash
(
"0xe7251ba12a5199190894e1c38c2bc80324901f054ccd2523640e47032630c560"
)
if
whash
!=
expected
{
t
.
Errorf
(
"expected %s, got %s"
,
expected
.
Hex
(),
whash
.
Hex
())
}
else
{
t
.
Logf
(
"success"
)
}
}
op-node/node/api.go
View file @
893bf27b
...
@@ -20,7 +20,7 @@ type l2Client interface {
...
@@ -20,7 +20,7 @@ type l2Client interface {
// GetProof returns a proof of the account, it may return a nil result without error if the address was not found.
// GetProof returns a proof of the account, it may return a nil result without error if the address was not found.
// Optionally keys of the account storage trie can be specified to include with corresponding values in the proof.
// Optionally keys of the account storage trie can be specified to include with corresponding values in the proof.
//GetProof(ctx context.Context, address common.Address, storage []common.Hash, blockTag string) (*eth.AccountResult, error)
//GetProof(ctx context.Context, address common.Address, storage []common.Hash, blockTag string) (*eth.AccountResult, error)
OutputV0AtBlock
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
(
*
eth
.
OutputV0
,
error
)
OutputV0AtBlock
(
ctx
context
.
Context
,
number
uint64
)
(
*
eth
.
OutputV0
,
error
)
WithdrawalProof
(
ctx
context
.
Context
,
txHash
common
.
Hash
)
(
*
eth
.
WithdrawalProof
,
error
)
WithdrawalProof
(
ctx
context
.
Context
,
txHash
common
.
Hash
)
(
*
eth
.
WithdrawalProof
,
error
)
WithdrawalTxs
(
ctx
context
.
Context
,
blockNumber
uint64
)
([]
common
.
Hash
,
error
)
WithdrawalTxs
(
ctx
context
.
Context
,
blockNumber
uint64
)
([]
common
.
Hash
,
error
)
}
}
...
@@ -135,7 +135,7 @@ func (n *nodeAPI) OutputAtBlock(ctx context.Context, number hexutil.Uint64) (*et
...
@@ -135,7 +135,7 @@ func (n *nodeAPI) OutputAtBlock(ctx context.Context, number hexutil.Uint64) (*et
return
nil
,
fmt
.
Errorf
(
"failed to get L2 block ref with sync status: %w"
,
err
)
return
nil
,
fmt
.
Errorf
(
"failed to get L2 block ref with sync status: %w"
,
err
)
}
}
output
,
err
:=
n
.
client
.
OutputV0AtBlock
(
ctx
,
ref
.
Hash
)
output
,
err
:=
n
.
client
.
OutputV0AtBlock
(
ctx
,
ref
.
Number
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to get L2 output at block %s: %w"
,
ref
,
err
)
return
nil
,
fmt
.
Errorf
(
"failed to get L2 output at block %s: %w"
,
ref
,
err
)
}
}
...
...
op-node/rollup/interop/managed/system.go
View file @
893bf27b
...
@@ -25,7 +25,7 @@ type L2Source interface {
...
@@ -25,7 +25,7 @@ type L2Source interface {
L2BlockRefByNumber
(
ctx
context
.
Context
,
num
uint64
)
(
eth
.
L2BlockRef
,
error
)
L2BlockRefByNumber
(
ctx
context
.
Context
,
num
uint64
)
(
eth
.
L2BlockRef
,
error
)
BlockRefByNumber
(
ctx
context
.
Context
,
num
uint64
)
(
eth
.
BlockRef
,
error
)
BlockRefByNumber
(
ctx
context
.
Context
,
num
uint64
)
(
eth
.
BlockRef
,
error
)
FetchReceipts
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
(
eth
.
BlockInfo
,
types
.
Receipts
,
error
)
FetchReceipts
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
(
eth
.
BlockInfo
,
types
.
Receipts
,
error
)
OutputV0AtBlock
(
ctx
context
.
Context
,
blockHash
common
.
Hash
)
(
*
eth
.
OutputV0
,
error
)
OutputV0AtBlock
(
ctx
context
.
Context
,
num
uint64
)
(
*
eth
.
OutputV0
,
error
)
}
}
type
L1Source
interface
{
type
L1Source
interface
{
...
@@ -290,7 +290,7 @@ func (m *ManagedMode) OutputV0AtTimestamp(ctx context.Context, timestamp uint64)
...
@@ -290,7 +290,7 @@ func (m *ManagedMode) OutputV0AtTimestamp(ctx context.Context, timestamp uint64)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
return
m
.
l2
.
OutputV0AtBlock
(
ctx
,
ref
.
Hash
)
return
m
.
l2
.
OutputV0AtBlock
(
ctx
,
ref
.
Number
)
}
}
func
(
m
*
ManagedMode
)
PendingOutputV0AtTimestamp
(
ctx
context
.
Context
,
timestamp
uint64
)
(
*
eth
.
OutputV0
,
error
)
{
func
(
m
*
ManagedMode
)
PendingOutputV0AtTimestamp
(
ctx
context
.
Context
,
timestamp
uint64
)
(
*
eth
.
OutputV0
,
error
)
{
...
@@ -305,5 +305,5 @@ func (m *ManagedMode) PendingOutputV0AtTimestamp(ctx context.Context, timestamp
...
@@ -305,5 +305,5 @@ func (m *ManagedMode) PendingOutputV0AtTimestamp(ctx context.Context, timestamp
// TODO: Once interop reorgs are supported (see #13645), replace with the output root preimage of an actual pending
// TODO: Once interop reorgs are supported (see #13645), replace with the output root preimage of an actual pending
// block contained in the optimistic block deposited transaction - https://github.com/ethereum-optimism/specs/pull/489
// block contained in the optimistic block deposited transaction - https://github.com/ethereum-optimism/specs/pull/489
// For now, we use the output at timestamp as-if it didn't contain invalid messages for happy path testing.
// For now, we use the output at timestamp as-if it didn't contain invalid messages for happy path testing.
return
m
.
l2
.
OutputV0AtBlock
(
ctx
,
ref
.
Hash
)
return
m
.
l2
.
OutputV0AtBlock
(
ctx
,
ref
.
Number
)
}
}
op-proposer/proposer/operator.go
View file @
893bf27b
...
@@ -285,7 +285,7 @@ func (l *Operator) DoOperator(ctx context.Context) {
...
@@ -285,7 +285,7 @@ func (l *Operator) DoOperator(ctx context.Context) {
TxHash
:
common
.
HexToHash
(
tx
.
TxHash
),
TxHash
:
common
.
HexToHash
(
tx
.
TxHash
),
}
}
for
i
,
p
:=
range
proof
.
Proof
{
for
i
,
p
:=
range
proof
.
Proof
{
params
.
WithdrawalProof
[
i
]
=
p
[
:
]
params
.
WithdrawalProof
[
i
]
=
common
.
HexToHash
(
p
)
.
Bytes
()
}
}
ooProof
:=
bindings
.
TypesOutputRootProof
{
ooProof
:=
bindings
.
TypesOutputRootProof
{
StateRoot
:
proof
.
Output
.
StateRoot
,
StateRoot
:
proof
.
Output
.
StateRoot
,
...
@@ -359,7 +359,7 @@ func (l *Operator) DoOperator(ctx context.Context) {
...
@@ -359,7 +359,7 @@ func (l *Operator) DoOperator(ctx context.Context) {
TxHash
:
common
.
HexToHash
(
tx
.
TxHash
),
TxHash
:
common
.
HexToHash
(
tx
.
TxHash
),
}
}
for
i
,
p
:=
range
proof
.
Proof
{
for
i
,
p
:=
range
proof
.
Proof
{
params
.
WithdrawalProof
[
i
]
=
p
[
:
]
params
.
WithdrawalProof
[
i
]
=
common
.
HexToHash
(
p
)
.
Bytes
()
}
}
ooProof
:=
bindings
.
TypesOutputRootProof
{
ooProof
:=
bindings
.
TypesOutputRootProof
{
StateRoot
:
proof
.
Output
.
StateRoot
,
StateRoot
:
proof
.
Output
.
StateRoot
,
...
...
op-service/eth/withdrawal_proof.go
View file @
893bf27b
...
@@ -7,7 +7,7 @@ import (
...
@@ -7,7 +7,7 @@ import (
type
WithdrawalProof
struct
{
type
WithdrawalProof
struct
{
Output
OutputV0
Output
OutputV0
Proof
[]
Bytes32
Proof
[]
string
Value
*
big
.
Int
Value
*
big
.
Int
User
common
.
Address
User
common
.
Address
Coin
[]
byte
Coin
[]
byte
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment