Skip to content

Commit

Permalink
Merge pull request #387 from ipfs-force-community/fix/nonce-repeat
Browse files Browse the repository at this point in the history
Fix/nonce repeat
  • Loading branch information
Vladmair authored Dec 3, 2024
2 parents 48f4d2e + 00a1103 commit b1e87c5
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 52 deletions.
66 changes: 65 additions & 1 deletion models/modules.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
package models

import (
"context"
"errors"
"fmt"
"time"

shared "github.com/filecoin-project/venus/venus-shared/types"
types "github.com/filecoin-project/venus/venus-shared/types/messager"
"github.com/ipfs-force-community/sophon-messager/filestore"
"github.com/ipfs-force-community/sophon-messager/models/mysql"
"github.com/ipfs-force-community/sophon-messager/models/repo"
"github.com/ipfs-force-community/sophon-messager/models/sqlite"
logging "github.com/ipfs/go-log/v2"
"go.uber.org/fx"
"gorm.io/gorm"
)

var log = logging.Logger("db")

func SetDataBase(fsRepo filestore.FSRepo) (repo.Repo, error) {
switch fsRepo.Config().DB.Type {
case "sqlite":
Expand All @@ -22,7 +31,10 @@ func SetDataBase(fsRepo filestore.FSRepo) (repo.Repo, error) {
}

func AutoMigrate(repo repo.Repo) error {
return repo.AutoMigrate()
if err := repo.AutoMigrate(); err != nil {
return fmt.Errorf("migrate: %w", err)
}
return MigrateAddress(repo)
}

func Options() fx.Option {
Expand All @@ -34,3 +46,55 @@ func Options() fx.Option {
fx.Provide(repo.NewINodeProvider),
)
}

func MigrateAddress(r repo.Repo) error {
ctx := context.Background()
list, err := r.AddressRepo().ListAddress(ctx)
if err != nil {
return err
}

return r.Transaction(func(txRepo repo.TxRepo) error {

for _, addrInfo := range list {
fAddr := addrInfo.Addr.String()
tAddr := "t" + fAddr[1:]
_, err := txRepo.AddressRepo().GetOneRecord(ctx, fAddr)
if err == nil {
if _, err := txRepo.AddressRepo().GetOneRecord(ctx, tAddr); err == nil {
if err := txRepo.AddressRepo().DelAddress(ctx, tAddr); err != nil {
return err
}
log.Infof("delete address %s success", tAddr)
}
continue
}
if !errors.Is(err, gorm.ErrRecordNotFound) {
return err
}

log.Infof("migrate address %s to %s", tAddr, fAddr)
now := time.Now()
newAddrInfo := &types.Address{
ID: shared.NewUUID(),
Addr: addrInfo.Addr,
Nonce: addrInfo.Nonce,
SelMsgNum: addrInfo.SelMsgNum,
State: addrInfo.State,
IsDeleted: repo.NotDeleted,
FeeSpec: addrInfo.FeeSpec,
CreatedAt: now,
UpdatedAt: now,
}
if err := txRepo.AddressRepo().SaveAddress(context.Background(), newAddrInfo); err != nil {
return err
}
log.Infof("migrate address %s to %s success", tAddr, fAddr)
if err := txRepo.AddressRepo().DelAddress(context.Background(), tAddr); err != nil {
return err
}
log.Infof("delete address %s success", tAddr)
}
return nil
})
}
16 changes: 8 additions & 8 deletions models/mysql/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ func (s mysqlAddressRepo) GetAddressByID(ctx context.Context, id shared.UUID) (*
return a.Address()
}

func (s mysqlAddressRepo) GetOneRecord(ctx context.Context, addr address.Address) (*types.Address, error) {
func (s mysqlAddressRepo) GetOneRecord(ctx context.Context, addr string) (*types.Address, error) {
var a mysqlAddress
if err := s.DB.WithContext(ctx).Take(&a, "addr = ?", addr.String()).Error; err != nil {
if err := s.DB.WithContext(ctx).Take(&a, "addr = ?", addr).Error; err != nil {
return nil, err
}

Expand Down Expand Up @@ -165,14 +165,14 @@ func (s mysqlAddressRepo) ListActiveAddress(ctx context.Context) ([]*types.Addre
return result, nil
}

func (s mysqlAddressRepo) DelAddress(ctx context.Context, addr address.Address) error {
return s.DB.WithContext(ctx).Model((*mysqlAddress)(nil)).Where("addr = ? and is_deleted = ?", addr.String(), repo.NotDeleted).
UpdateColumns(map[string]interface{}{"is_deleted": repo.Deleted, "state": types.AddressStateRemoved, "updated_at": time.Now()}).Error
func (s mysqlAddressRepo) DelAddress(ctx context.Context, addr string) error {
return s.DB.WithContext(ctx).Where("addr = ?", addr).Delete(&mysqlAddress{}).Error
}

func (s mysqlAddressRepo) UpdateNonce(ctx context.Context, addr address.Address, nonce uint64) error {
return s.DB.WithContext(ctx).Model(&mysqlAddress{}).Where("addr = ? and is_deleted = ?", addr.String(), repo.NotDeleted).
UpdateColumns(map[string]interface{}{"nonce": nonce, "updated_at": time.Now()}).Error
func (s mysqlAddressRepo) UpdateNonce(addr address.Address, nonce uint64) (int64, error) {
query := s.DB.Model(&mysqlAddress{}).Where("addr = ? and is_deleted = ?", addr.String(), repo.NotDeleted).
UpdateColumns(map[string]interface{}{"nonce": nonce, "updated_at": time.Now()})
return query.RowsAffected, query.Error
}

func (s mysqlAddressRepo) UpdateState(ctx context.Context, addr address.Address, state types.AddressState) error {
Expand Down
11 changes: 5 additions & 6 deletions models/mysql/address_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func testGetOneRecord(t *testing.T, r repo.Repo, mock sqlmock.Sqlmock) {
WithArgs(addr.String()).
WillReturnRows(sqlmock.NewRows([]string{"addr"}).AddRow(addr.String()))

res, err := r.AddressRepo().GetOneRecord(ctx, addr)
res, err := r.AddressRepo().GetOneRecord(ctx, addr.String())
assert.NoError(t, err)
assert.Equal(t, addr, res.Addr)
}
Expand Down Expand Up @@ -153,17 +153,16 @@ func testDelAddress(t *testing.T, r repo.Repo, mock sqlmock.Sqlmock) {

mock.ExpectBegin()
mock.ExpectExec(regexp.QuoteMeta(
"UPDATE `addresses` SET `is_deleted`=?,`state`=?,`updated_at`=? WHERE addr = ? and is_deleted = ?")).
WithArgs(repo.Deleted, types.AddressStateRemoved, anyTime{}, addr.String(), repo.NotDeleted).
"DELETE FROM `addresses` WHERE addr = ?")).
WithArgs(addr.String()).
WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectCommit()

err := r.AddressRepo().DelAddress(ctx, addr)
err := r.AddressRepo().DelAddress(ctx, addr.String())
assert.NoError(t, err)
}

func testUpdateNonce(t *testing.T, r repo.Repo, mock sqlmock.Sqlmock) {
ctx := context.Background()
addr := testutil.AddressProvider()(t)
nonce := uint64(10)

Expand All @@ -174,7 +173,7 @@ func testUpdateNonce(t *testing.T, r repo.Repo, mock sqlmock.Sqlmock) {
WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectCommit()

err := r.AddressRepo().UpdateNonce(ctx, addr, nonce)
_, err := r.AddressRepo().UpdateNonce(addr, nonce)
assert.NoError(t, err)
}

Expand Down
6 changes: 3 additions & 3 deletions models/repo/address_repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ type AddressRepo interface {
SaveAddress(ctx context.Context, address *types.Address) error
GetAddress(ctx context.Context, addr address.Address) (*types.Address, error)
GetAddressByID(ctx context.Context, id shared.UUID) (*types.Address, error)
GetOneRecord(ctx context.Context, addr address.Address) (*types.Address, error)
GetOneRecord(ctx context.Context, addr string) (*types.Address, error)
HasAddress(ctx context.Context, addr address.Address) (bool, error)
ListAddress(ctx context.Context) ([]*types.Address, error)
ListActiveAddress(ctx context.Context) ([]*types.Address, error)
DelAddress(ctx context.Context, addr address.Address) error
UpdateNonce(ctx context.Context, addr address.Address, nonce uint64) error
DelAddress(ctx context.Context, addr string) error
UpdateNonce(addr address.Address, nonce uint64) (int64, error)
UpdateState(ctx context.Context, addr address.Address, state types.AddressState) error
UpdateSelectMsgNum(ctx context.Context, addr address.Address, num uint64) error
UpdateFeeParams(ctx context.Context, addr address.Address, gasOverEstimation, gasOverPremium float64, maxFee, gasFeeCap, baseFee big.Int) error
Expand Down
16 changes: 8 additions & 8 deletions models/sqlite/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,9 @@ func (s sqliteAddressRepo) GetAddressByID(ctx context.Context, id shared.UUID) (
return a.Address()
}

func (s sqliteAddressRepo) GetOneRecord(ctx context.Context, addr address.Address) (*types.Address, error) {
func (s sqliteAddressRepo) GetOneRecord(ctx context.Context, addr string) (*types.Address, error) {
var a sqliteAddress
if err := s.DB.WithContext(ctx).Take(&a, "addr = ?", addr.String()).Error; err != nil {
if err := s.DB.WithContext(ctx).Take(&a, "addr = ?", addr).Error; err != nil {
return nil, err
}

Expand Down Expand Up @@ -164,9 +164,10 @@ func (s sqliteAddressRepo) ListActiveAddress(ctx context.Context) ([]*types.Addr
return result, nil
}

func (s sqliteAddressRepo) UpdateNonce(ctx context.Context, addr address.Address, nonce uint64) error {
return s.DB.WithContext(ctx).Model((*sqliteAddress)(nil)).Where("addr = ? and is_deleted = -1", addr.String()).
UpdateColumns(map[string]interface{}{"nonce": nonce, "updated_at": time.Now()}).Error
func (s sqliteAddressRepo) UpdateNonce(addr address.Address, nonce uint64) (int64, error) {
query := s.DB.Model((*sqliteAddress)(nil)).Where("addr = ? and is_deleted = -1", addr.String()).
UpdateColumns(map[string]interface{}{"nonce": nonce, "updated_at": time.Now()})
return query.RowsAffected, query.Error
}

func (s sqliteAddressRepo) UpdateState(ctx context.Context, addr address.Address, state types.AddressState) error {
Expand Down Expand Up @@ -205,9 +206,8 @@ func (s sqliteAddressRepo) UpdateFeeParams(ctx context.Context, addr address.Add
return s.DB.WithContext(ctx).Model((*sqliteAddress)(nil)).Where("addr = ? and is_deleted = -1", addr.String()).UpdateColumns(updateColumns).Error
}

func (s sqliteAddressRepo) DelAddress(ctx context.Context, addr address.Address) error {
return s.DB.WithContext(ctx).Model((*sqliteAddress)(nil)).Where("addr = ? and is_deleted = -1", addr.String()).
UpdateColumns(map[string]interface{}{"is_deleted": repo.Deleted, "state": types.AddressStateRemoved, "updated_at": time.Now()}).Error
func (s sqliteAddressRepo) DelAddress(ctx context.Context, addr string) error {
return s.DB.WithContext(ctx).Where("addr = ?", addr).Delete(&sqliteAddress{}).Error
}

var _ repo.AddressRepo = &sqliteAddressRepo{}
17 changes: 8 additions & 9 deletions models/sqlite/address_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/stretchr/testify/assert"
"gorm.io/gorm"

"github.com/ipfs-force-community/sophon-messager/models/repo"
"github.com/ipfs-force-community/sophon-messager/testhelper"
)

Expand Down Expand Up @@ -116,13 +115,14 @@ func TestAddress(t *testing.T) {

t.Run("UpdateNonce", func(t *testing.T) {
nonce := uint64(5)
assert.NoError(t, addressRepo.UpdateNonce(ctx, addrInfo.Addr, nonce))
_, err := addressRepo.UpdateNonce(addrInfo.Addr, nonce)
assert.NoError(t, err)
r, err := addressRepo.GetAddress(ctx, addrInfo.Addr)
assert.NoError(t, err)
assert.Equal(t, nonce, r.Nonce)

// set nonce for a not exist address
err = addressRepo.UpdateNonce(ctx, randAddr, nonce)
_, err = addressRepo.UpdateNonce(randAddr, nonce)
assert.NoError(t, err)
_, err = addressRepo.GetAddress(ctx, randAddr)
assert.Contains(t, err.Error(), gorm.ErrRecordNotFound.Error())
Expand Down Expand Up @@ -191,19 +191,18 @@ func TestAddress(t *testing.T) {
})

t.Run("DelAddress", func(t *testing.T) {
assert.NoError(t, addressRepo.DelAddress(ctx, addrInfo2.Addr))
assert.NoError(t, addressRepo.DelAddress(ctx, addrInfo2.Addr.String()))

r, err := addressRepo.GetAddress(ctx, addrInfo2.Addr)
assert.Error(t, err)
assert.Nil(t, r)

r, err = addressRepo.GetOneRecord(ctx, addrInfo2.Addr)
assert.NoError(t, err)
assert.Equal(t, types.AddressStateRemoved, r.State)
assert.Equal(t, repo.Deleted, r.IsDeleted)
r, err = addressRepo.GetOneRecord(ctx, addrInfo2.Addr.String())
assert.Error(t, err)
assert.Nil(t, r)

// delete a not exist address
err = addressRepo.DelAddress(ctx, randAddr)
err = addressRepo.DelAddress(ctx, randAddr.String())
assert.NoError(t, err)
_, err = addressRepo.GetAddress(ctx, randAddr)
assert.Contains(t, err.Error(), gorm.ErrRecordNotFound.Error())
Expand Down
7 changes: 4 additions & 3 deletions service/address_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ func (addressService *AddressService) SaveAddress(ctx context.Context, address *
return address.ID, err
}

func (addressService *AddressService) UpdateNonce(ctx context.Context, addr address.Address, nonce uint64) error {
return addressService.repo.AddressRepo().UpdateNonce(ctx, addr, nonce)
func (addressService *AddressService) UpdateNonce(_ context.Context, addr address.Address, nonce uint64) error {
_, err := addressService.repo.AddressRepo().UpdateNonce(addr, nonce)
return err
}

func (addressService *AddressService) GetAddress(ctx context.Context, addr address.Address) (*types.Address, error) {
Expand Down Expand Up @@ -120,7 +121,7 @@ func (addressService *AddressService) ListActiveAddress(ctx context.Context) ([]
}

func (addressService *AddressService) DeleteAddress(ctx context.Context, addr address.Address) error {
return addressService.repo.AddressRepo().DelAddress(ctx, addr)
return addressService.repo.AddressRepo().DelAddress(ctx, addr.String())
}

func (addressService *AddressService) ForbiddenAddress(ctx context.Context, addr address.Address) error {
Expand Down
Loading

0 comments on commit b1e87c5

Please sign in to comment.