Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
310bf79
fix
hundredark Dec 8, 2025
421aa00
remove ethereum refund action
hundredark Dec 8, 2025
226d635
slight fixes
hundredark Dec 8, 2025
8853a44
add more checks
hundredark Dec 8, 2025
6dc0244
slight fix
hundredark Dec 8, 2025
ffd56d1
mark tx stuck
hundredark Dec 9, 2025
4a5458f
keeper handle cancel tx
hundredark Dec 9, 2025
a83950f
should not increase safe nonce when finish cancel tx signature
hundredark Dec 9, 2025
480dc1a
shoud check balance
hundredark Dec 9, 2025
33399b9
should update balance for canceled tx
hundredark Dec 9, 2025
6294606
slight fix
hundredark Dec 10, 2025
3dcfd6b
add more test
hundredark Dec 10, 2025
1d20dc9
slight improve
hundredark Dec 10, 2025
7007b30
more test
hundredark Dec 10, 2025
ed8ed79
slight improve
hundredark Dec 10, 2025
d99bc4d
update stuck tx state after new tx being sent
hundredark Dec 10, 2025
50d7549
fix spent hash
hundredark Dec 10, 2025
3af2346
slight improves
hundredark Dec 10, 2025
09572cd
cannot use balance locked in stuck tx when propose new tx to cancel
hundredark Dec 11, 2025
e95b131
fix test
hundredark Dec 11, 2025
3a26da4
add some codes for test
hundredark Dec 12, 2025
1b272db
fix tx state
hundredark Dec 12, 2025
381556a
slight fix
hundredark Dec 12, 2025
d090902
fix old tx state
hundredark Dec 15, 2025
5f4ef41
typo
hundredark Dec 15, 2025
6771358
more checks on nonce
hundredark Dec 15, 2025
cfd72a0
fix observer migration
hundredark Dec 15, 2025
fb3ff25
add keeper migration
hundredark Dec 15, 2025
af775ae
improve log
hundredark Dec 15, 2025
285abbc
fix test
hundredark Dec 15, 2025
1cbbbbc
Merge branch 'main' into bugfix/eth-valid-tx
hundredark Dec 16, 2025
21b5acc
fix test
hundredark Dec 16, 2025
8918579
fix test
hundredark Dec 16, 2025
66c9e37
hide some checks for test
hundredark Dec 16, 2025
8a1a4b7
fix nonce
hundredark Dec 16, 2025
2f55db8
should refund safe token when finish cancel tx
hundredark Dec 16, 2025
e249732
slight fix
hundredark Dec 16, 2025
4c577ad
add more logs
hundredark Dec 16, 2025
628e847
fix trace id
hundredark Dec 16, 2025
e7f8325
improve tx sending
hundredark Dec 17, 2025
2f5a0e6
slight improve
hundredark Dec 17, 2025
1e48cc8
remove codes for testnet
hundredark Dec 17, 2025
050e5bf
update some migration sql
cedricfung Dec 23, 2025
791bc7d
remove some test code
cedricfung Dec 23, 2025
6a8bfe9
small fixes
cedricfung Dec 25, 2025
d3ca16c
better nonce check
cedricfung Dec 26, 2025
59941d3
use correct nonce
cedricfung Dec 26, 2025
0f68313
slight fixes
hundredark Dec 26, 2025
efb230b
improve tx sending
hundredark Dec 26, 2025
36efed6
remove ExecTransaction
hundredark Dec 26, 2025
99ea09d
close ethclient
cedricfung Dec 26, 2025
801e97e
Merge remote-tracking branch 'origin/main' into bugfix/eth-valid-tx
cedricfung Dec 26, 2025
eaf17e4
fix stuck
hundredark Dec 26, 2025
ff9b930
small fixes
cedricfung Dec 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion apps/ethereum/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,11 @@ func GetOrDeploySafeAccount(ctx context.Context, rpc, key string, chainId int64,
}
}
if !isGuarded {
_, err := tx.ExecTransaction(ctx, rpc, key)
etx, err := tx.BuildTransaction(ctx, rpc, key)
if err != nil {
return nil, err
}
err = SendAndWaitMined(ctx, rpc, etx)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -280,6 +284,24 @@ func ParseEthereumCompressedPublicKey(public string) (*common.Address, error) {
return &addr, nil
}

func FetchSafeNonce(ctx context.Context, rpc, address string, height int64) (int64, error) {
conn, abi, err := safeInit(rpc, address)
if err != nil {
return 0, err
}
defer conn.Close()

opt := &bind.CallOpts{}
if height > 0 {
opt.BlockNumber = big.NewInt(height)
}
nonce, err := abi.Nonce(opt)
if err != nil {
return 0, err
}
return nonce.Int64(), nil
}

func FetchBalanceFromKey(ctx context.Context, rpc, key string) (*big.Int, error) {
addr, err := PrivToAddress(key)
if err != nil {
Expand Down
16 changes: 11 additions & 5 deletions apps/ethereum/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,18 +115,24 @@ func RPCGetBlockHeight(rpc string) (int64, error) {
return int64(height), err
}

func RPCGetBlockHash(rpc string, height int64) (string, error) {
func RPCGetBlockByHeight(rpc string, height int64) (*RPCBlock, error) {
h := fmt.Sprintf("0x%x", height)
res, err := callEthereumRPCUntilSufficient(rpc, "eth_getBlockByNumber", []any{h, false})
if err != nil {
return "", err
return nil, err
}
var b *RPCBlock
err = json.Unmarshal(res, &b)
if err != nil || b == nil {
return "", err
if err != nil {
return nil, err
}
return b.Hash, err

timestamp, err := ethereumNumberToUint64(b.Timestamp)
if err != nil {
return nil, err
}
b.Time = time.Unix(int64(timestamp), 0)
return b, err
}

func RPCGetBlockWithTransactions(rpc string, height int64) (*RPCBlockWithTransactions, error) {
Expand Down
40 changes: 29 additions & 11 deletions apps/ethereum/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import (
ga "github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"golang.org/x/crypto/sha3"
)

Expand Down Expand Up @@ -256,10 +258,10 @@ func UnmarshalSafeTransaction(b []byte) (*SafeTransaction, error) {
}, nil
}

func (tx *SafeTransaction) ValidTransaction(rpc string) (bool, error) {
func (tx *SafeTransaction) ValidTransaction(rpc string) error {
conn, abi, err := safeInit(rpc, tx.SafeAddress)
if err != nil {
return false, err
return err
}
defer conn.Close()

Expand All @@ -273,10 +275,10 @@ func (tx *SafeTransaction) ValidTransaction(rpc string) (bool, error) {
count += 1
}
if count < 2 {
return false, fmt.Errorf("SafeTransaction has insufficient signatures")
return fmt.Errorf("SafeTransaction has insufficient signatures")
}

return abi.ValidTransaction(
success, err := abi.ValidTransaction(
tx.Destination,
tx.Value,
tx.Data,
Expand All @@ -288,12 +290,16 @@ func (tx *SafeTransaction) ValidTransaction(rpc string) (bool, error) {
tx.RefundReceiver,
signature,
)
if !success || err != nil {
return fmt.Errorf("ValidTransaction(%s) => %t %v", tx.TxHash, success, err)
}
return nil
}

func (tx *SafeTransaction) ExecTransaction(ctx context.Context, rpc, key string) (string, error) {
func (tx *SafeTransaction) BuildTransaction(ctx context.Context, rpc, key string) (*types.Transaction, error) {
conn, safeAbi, err := safeInit(rpc, tx.SafeAddress)
if err != nil {
return "", err
return nil, err
}
defer conn.Close()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This connection should not be returned, and also already closed.

signer := SignerInit(ctx, conn, key, tx.ChainID)
Expand All @@ -308,9 +314,10 @@ func (tx *SafeTransaction) ExecTransaction(ctx context.Context, rpc, key string)
count += 1
}
if count < 2 {
return "", fmt.Errorf("SafeTransaction has insufficient signatures")
return nil, fmt.Errorf("SafeTransaction has insufficient signatures")
}

signer.NoSend = true
t, err := safeAbi.ExecTransaction(
signer,
tx.Destination,
Expand All @@ -325,13 +332,24 @@ func (tx *SafeTransaction) ExecTransaction(ctx context.Context, rpc, key string)
signature,
)
if err != nil {
return "", err
return nil, err
}
_, err = bind.WaitMined(ctx, conn, t)
return t, nil
}

func SendAndWaitMined(ctx context.Context, rpc string, t *types.Transaction) error {
conn, err := ethclient.Dial(rpc)
if err != nil {
return "", err
return err
}
return t.Hash().Hex(), nil
defer conn.Close()

err = conn.SendTransaction(ctx, t)
if err != nil {
return err
}
_, err = bind.WaitMined(ctx, conn, t)
return err
}

func (tx *SafeTransaction) ExtractOutputs() []*Output {
Expand Down
7 changes: 4 additions & 3 deletions common/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,14 @@ const (
ActionEthereumSafeApproveTransaction = 133
ActionEthereumSafeRevokeTransaction = 134
ActionEthereumSafeCloseAccount = 135
ActionEthereumSafeRefundTransaction = 136
ActionEthereumSafeRefundTransaction = 136 // deprecated
ActionEthereumSafeCloseAccountByInheritance = 137

FlagProposeNormalTransaction = 0
FlagProposeRecoveryTransaction = 1
FlagProposeSetInheritance = 2
FlagProposeRemoveInheritance = 3
FlagProposeCancelTransaction = 2
FlagProposeSetInheritance = 3
FlagProposeRemoveInheritance = 4
)

type Request struct {
Expand Down
14 changes: 6 additions & 8 deletions keeper/bitcoin.go
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,9 @@ func (node *Node) processBitcoinSafeApproveTransaction(ctx context.Context, req
}

func (node *Node) processBitcoinSafeSignatureResponse(ctx context.Context, req *common.Request, safe *store.Safe, tx *store.Transaction, old *store.SignatureRequest) ([]*mtg.Transaction, string) {
if tx.TransactionHash != old.TransactionHash {
panic(old.TransactionHash)
}
if req.Role != common.RequestRoleSigner {
panic(req.Role)
}
Expand Down Expand Up @@ -1021,7 +1024,7 @@ func (node *Node) processBitcoinSafeSignatureResponse(ctx context.Context, req *
lock := node.finalizePendingSafeInheritanceLock(ctx, tx)
logger.Printf("node.finalizePendingSafeInheritanceLock(%s) => %v", tx.RequestId, lock)
raw := hex.EncodeToString(spsbt.Marshal())
err = node.store.FinishTransactionSignaturesWithRequest(ctx, old.TransactionHash, raw, req, int64(len(msgTx.TxIn)), safe, nil, lock, txs)
err = node.store.FinishTransactionSignaturesWithRequest(ctx, tx, raw, req, int64(len(msgTx.TxIn)), safe, nil, lock, txs)
logger.Printf("store.FinishTransactionSignaturesWithRequest(%s, %s, %v, %v) => %v", old.TransactionHash, raw, req, lock, err)
if err != nil {
panic(err)
Expand Down Expand Up @@ -1133,12 +1136,7 @@ func (node *Node) processSafeInheritanceLock(ctx context.Context, req *common.Re
}

func (node *Node) finalizePendingSafeInheritanceLock(ctx context.Context, tx *store.Transaction) *store.InheritanceLock {
txReq, err := node.store.ReadRequest(ctx, tx.RequestId)
if err != nil {
panic(err)
}
extra := txReq.ExtraBytes()
flag := extra[0]
flag, extra := node.getTransactionFlagAndExtra(ctx, tx.RequestId)
switch flag {
case common.FlagProposeSetInheritance:
lock, err := node.store.ReadInheritanceLockByRequestId(ctx, tx.RequestId)
Expand All @@ -1152,7 +1150,7 @@ func (node *Node) finalizePendingSafeInheritanceLock(ctx context.Context, tx *st
lock.State = common.RequestStateDone
return lock
case common.FlagProposeRemoveInheritance:
lid, err := uuid.FromBytes(extra[1:17])
lid, err := uuid.FromBytes(extra[:16])
if err != nil || lid.IsNil() {
logger.Printf("invalid lock id to remove: %v %v", lid, err)
return nil
Expand Down
Loading
Loading