Skip to content

Commit

Permalink
change Deposit logic
Browse files Browse the repository at this point in the history
  • Loading branch information
Jackmeng1985 committed Jun 13, 2023
1 parent 4cc3f9c commit 11373f2
Show file tree
Hide file tree
Showing 4 changed files with 214 additions and 58 deletions.
169 changes: 133 additions & 36 deletions contracts/deposit/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"bytes"
"context"
"embed"
"errors"
"github.com/amazechain/amc/common"
"github.com/amazechain/amc/common/crypto"
"github.com/amazechain/amc/common/crypto/bls"
Expand Down Expand Up @@ -186,7 +187,14 @@ func (d Deposit) eventLoop() {
}
case logRemovedEvent := <-d.rmLogsCh:
for _, l := range logRemovedEvent.Logs {
log.Info("logEvent", "address", l.Address, "data", l.Data, "")
if nil != d.consensusConfig.APos && bytes.Compare(l.Address[:], depositContractByes[:]) == 0 {
log.Trace("log event topic[0]= ", "hash", l.Topics[0], "depositEventSignature", depositEventSignature, "withdrawnSignature", withdrawnSignature)
if l.Topics[0] == depositEventSignature {
d.handleUndoDepositEvent(l.TxHash, l.Data)
} else if l.Topics[0] == withdrawnSignature {
d.handleWithdrawnEvent(l.TxHash, l.Data)
}
}
}
case <-d.logsSub.Err():
return
Expand All @@ -198,64 +206,121 @@ func (d Deposit) eventLoop() {
}
}

func (d Deposit) handleDepositEvent(txHash types.Hash, data []byte) {
func (d Deposit) verifySignature(sig []byte, pub []byte, depositAmount *uint256.Int) error {
// 1
signature, err := bls.SignatureFromBytes(sig)
if err != nil {
log.Warn("cannot unpack BLS signature", "signature", hexutil.Encode(sig), "err", err)
return err
}
// 2
publicKey, err := bls.PublicKeyFromBytes(pub)
if err != nil {
log.Warn("cannot unpack BLS publicKey", "publicKey", hexutil.Encode(pub), "err", err)
return err
}
// 3
log.Trace("DepositEvent verify:", "signature", hexutil.Encode(signature.Marshal()), "publicKey", hexutil.Encode(publicKey.Marshal()), "msg", hexutil.Encode(depositAmount.Bytes()))
if !signature.Verify(publicKey, depositAmount.Bytes()) {
return errors.New("cannot Verify signature")
}

return nil
}

func (d Deposit) handleDepositEvent(txHash types.Hash, data []byte) {

pb, amount, sig, err := UnpackDepositLogData(data)
if err != nil {
log.Warn("cannot unpack deposit log data")
return
}
// 2
signature, err := bls.SignatureFromBytes(sig)

if err := d.verifySignature(sig, pb, amount); err != nil {
log.Error("cannot Verify signature", "signature", hexutil.Encode(sig), "publicKey", hexutil.Encode(pb), "message", hexutil.Encode(amount.Bytes()), "err", err)
return
}

rwTx, err := d.db.BeginRw(d.ctx)
defer rwTx.Rollback()
if err != nil {
log.Warn("cannot unpack BLS signature", "signature", hexutil.Encode(sig), "err", err)
log.Error("cannot open db", "err", err)
return
}
// 3
publicKey, err := bls.PublicKeyFromBytes(pb)

var tx *transaction.Transaction
tx, _, _, _, err = rawdb.ReadTransactionByHash(rwTx, txHash)
if err != nil {
log.Warn("cannot unpack BLS publicKey", "publicKey", hexutil.Encode(pb), "err", err)
log.Error("cannot read transaction by hash", "err", err, "hash", txHash)
}
if tx == nil {
log.Error("cannot read transaction by hash", "err", err, "hash", txHash)
}

var pub types.PublicKey
_ = pub.SetBytes(pb)
//
if err = rawdb.DoDeposit(rwTx, *tx.From(), pub, amount); err != nil {
log.Error("cannot modify database", "err", err)
}
if err = rwTx.Commit(); err != nil {
log.Error("cannot commit tx", "err", err)
}
}

func (d Deposit) handleUndoDepositEvent(txHash types.Hash, data []byte) {
pb, amount, sig, err := UnpackDepositLogData(data)
if err != nil {
log.Warn("cannot unpack deposit log data")
return
}
// 4
log.Trace("DepositEvent verify:", "signature", hexutil.Encode(signature.Marshal()), "publicKey", hexutil.Encode(publicKey.Marshal()), "msg", hexutil.Encode(amount.Bytes()))
if signature.Verify(publicKey, amount.Bytes()) {
var tx *transaction.Transaction
rwTx, err := d.db.BeginRw(d.ctx)
defer rwTx.Rollback()
if err != nil {
log.Error("cannot open db", "err", err)
return
}

tx, _, _, _, err = rawdb.ReadTransactionByHash(rwTx, txHash)
if err != nil {
log.Error("rawdb.ReadTransactionByHash", "err", err, "hash", txHash)
}
if err := d.verifySignature(sig, pb, amount); err != nil {
log.Error("cannot Verify signature", "signature", hexutil.Encode(sig), "publicKey", hexutil.Encode(pb), "message", hexutil.Encode(amount.Bytes()), "err", err)
return
}

if tx != nil {
log.Trace("add Deposit info", "address", tx.From(), "amount", amount.String())
rwTx, err := d.db.BeginRw(d.ctx)
defer rwTx.Rollback()
if err != nil {
log.Error("cannot open db", "err", err)
return
}

var pub types.PublicKey
pub.SetBytes(publicKey.Marshal())
//
rawdb.PutDeposit(rwTx, *tx.From(), pub, *amount)
rwTx.Commit()
}
} else {
log.Error("DepositEvent cannot Verify signature", "signature", hexutil.Encode(sig), "publicKey", hexutil.Encode(pb), "message", hexutil.Encode(amount.Bytes()), "err", err)
var tx *transaction.Transaction
tx, _, _, _, err = rawdb.ReadTransactionByHash(rwTx, txHash)
if err != nil {
log.Error("cannot read transaction by hash", "err", err, "hash", txHash)
}
if tx == nil {
log.Error("cannot read transaction by hash", "err", err, "hash", txHash)
}

//
if err = rawdb.UndoDeposit(rwTx, *tx.From(), amount); err != nil {
log.Error("cannot modify database", "err", err)
}
if err = rwTx.Commit(); err != nil {
log.Error("cannot commit tx", "err", err)
}

}

func (d Deposit) handleWithdrawnEvent(txHash types.Hash, data []byte) {
var tx *transaction.Transaction
// 1
amount, err := UnpackWithdrawnLogData(data)
if err != nil {
log.Warn("cannot unpack deposit log data")
return
}

rwTx, err := d.db.BeginRw(d.ctx)
defer rwTx.Rollback()
if err != nil {
log.Error("cannot open db", "err", err)
return
}
var tx *transaction.Transaction
tx, _, _, _, err = rawdb.ReadTransactionByHash(rwTx, txHash)
if err != nil {
log.Error("rawdb.ReadTransactionByHash", "err", err, "hash", txHash)
Expand All @@ -266,10 +331,42 @@ func (d Deposit) handleWithdrawnEvent(txHash types.Hash, data []byte) {
return
}

err = rawdb.DeleteDeposit(rwTx, *tx.From())
err = rawdb.DoWithdrawn(rwTx, *tx.From(), amount)
if err != nil {
log.Error("cannot delete deposit", "err", err)
log.Error("cannot Withdrawn deposit when handle Withdrawn Event", "err", err)
return
}
rwTx.Commit()
if err = rwTx.Commit(); nil != err {
log.Error("cannot commit when handle Withdrawn Event", "err", err)
}
}

func (d Deposit) handleUndoWithdrawnEvent(txHash types.Hash, data []byte) {
amount, err := UnpackWithdrawnLogData(data)
if err != nil {
log.Warn("cannot unpack deposit log data")
return
}
rwTx, err := d.db.BeginRw(d.ctx)
defer rwTx.Rollback()

var tx *transaction.Transaction
tx, _, _, _, err = rawdb.ReadTransactionByHash(rwTx, txHash)
if err != nil {
log.Error("rawdb.ReadTransactionByHash", "err", err, "hash", txHash)
return
}
if tx == nil {
log.Error("cannot find Transaction", "err", err, "hash", txHash)
return
}

if err = rawdb.UndoWithdrawn(rwTx, *tx.From(), amount); err != nil {
log.Error("cannot Undo Withdrawn deposit when handle remove Withdrawn log Event", "err", err)
return
}

if err = rwTx.Commit(); nil != err {
log.Error("cannot commit when handle Withdrawn Event", "err", err)
}
}
22 changes: 22 additions & 0 deletions contracts/deposit/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,25 @@ func UnpackDepositLogData(data []byte) (pubkey []byte, amount *uint256.Int, sign

return unpackedLogs[0].([]byte), amount, unpackedLogs[2].([]byte), nil
}

// UnpackWithdrawnLogData unpacks the data from a deposit log using the ABI decoder.
func UnpackWithdrawnLogData(data []byte) (amount *uint256.Int, err error) {
reader := bytes.NewReader(depositAbiCode)
contractAbi, err := abi.JSON(reader)
if err != nil {
return nil, errors.Wrap(err, "unable to generate contract abi")
}

unpackedLogs, err := contractAbi.Unpack("WithdrawnEvent", data)
if err != nil {
return nil, errors.Wrap(err, "unable to unpack logs")
}
amount, overflow := uint256.FromBig(unpackedLogs[0].(*big.Int))
if overflow {
return nil, errors.New("unable to unpack amount")
}

log.Debug("unpacked WithdrawnEvent Logs", "message", hexutil.Encode(amount.Bytes()))

return amount, nil
}
79 changes: 57 additions & 22 deletions modules/rawdb/accessors_deposit.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,12 @@ import (
"fmt"
"github.com/amazechain/amc/common/crypto/bls"
"github.com/amazechain/amc/common/types"
"github.com/amazechain/amc/common/u256"
"github.com/amazechain/amc/modules"
"github.com/holiman/uint256"
"github.com/ledgerwatch/erigon-lib/kv"
)

//// PutDeposit
//func PutDeposit(db kv.Putter, key []byte, val []byte) error {
// return db.Put(modules.Deposit, key, val)
//}

func PutDeposit(db kv.Putter, addr types.Address, pub types.PublicKey, amount uint256.Int) error {

data := make([]byte, types.PublicKeyLength+amount.ByteLen())
copy(data[:types.PublicKeyLength], pub.Bytes())
copy(data[types.PublicKeyLength:], amount.Bytes())
//
if err := db.Put(modules.Deposit, addr[:], data); err != nil {
return fmt.Errorf("failed to store address Deposit: %w", err)
}
return nil
}

// GetDeposit
func GetDeposit(db kv.Getter, addr types.Address) (types.PublicKey, *uint256.Int, error) {
valBytes, err := db.GetOne(modules.Deposit, addr[:])
Expand All @@ -64,15 +48,66 @@ func GetDeposit(db kv.Getter, addr types.Address) (types.PublicKey, *uint256.Int
return *pubkey, amount, nil
}

// DeleteDeposit removes Deposit data associated with an address.
func DeleteDeposit(db kv.Deleter, addr types.Address) error {
return db.Delete(modules.Deposit, addr[:])
func DoDeposit(db kv.Putter, addr types.Address, pub types.PublicKey, amount *uint256.Int) error {

data := make([]byte, types.PublicKeyLength+amount.ByteLen())
copy(data[:types.PublicKeyLength], pub.Bytes())
copy(data[types.PublicKeyLength:], amount.Bytes())
//
if err := db.Put(modules.Deposit, addr[:], data); err != nil {
return fmt.Errorf("failed to store address Deposit: %w", err)
}
return nil
}

func UndoDeposit(db kv.Putter, addr types.Address, amount *uint256.Int) error {
pub, dbAmount, err := GetDeposit(db.(kv.Getter), addr)
if err != nil {
return fmt.Errorf("cannot get deposit")
}
if dbAmount.Cmp(amount) != 0 {
return fmt.Errorf("dbAmount != withdrawnAmount")
}
return DoDeposit(db, addr, pub, new(uint256.Int))
}

// DoWithdrawn removes Deposit data associated with an address.
func DoWithdrawn(db kv.RwTx, addr types.Address, withdrawnAmount *uint256.Int) error {
pub, dbAmount, err := GetDeposit(db, addr)
if err != nil {
return fmt.Errorf("cannot get deposit")
}
if dbAmount.Cmp(withdrawnAmount) != 0 {
return fmt.Errorf("dbAmount != withdrawnAmount")
}
return DoDeposit(db, addr, pub, new(uint256.Int))
}

func UndoWithdrawn(db kv.RwTx, addr types.Address, unDoWithdrawnAmount *uint256.Int) error {
pub, dbAmount, err := GetDeposit(db, addr)
if err != nil {
return fmt.Errorf("cannot get deposit")
}
if dbAmount.Cmp(u256.Num0) != 0 {
return fmt.Errorf("db deposit != 0 when undo withdrawn")
}
return DoDeposit(db, addr, pub, unDoWithdrawnAmount)
}

// IsDeposit is deposit account
func IsDeposit(db kv.Getter, addr types.Address) bool {
is, _ := db.Has(modules.Deposit, addr[:])
return is
//
//is, _ := db.Has(modules.Deposit, addr[:])
_, amount, err := GetDeposit(db, addr)
if err != nil {
return false
}

if amount.Cmp(u256.Num0) == 0 {
return false
}
//
return true
}

func DepositNum(tx kv.Tx) (uint64, error) {
Expand Down
2 changes: 2 additions & 0 deletions modules/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ var AmcTableCfg = kv.TableCfg{
DupFromLen: 54,
DupToLen: 34,
},
//
Deposit: {Flags: kv.DupSort},
}

func AmcInit() {
Expand Down

0 comments on commit 11373f2

Please sign in to comment.