Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature(api): GET Tx ID by Event ID #233

Merged
merged 23 commits into from
Apr 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
48d2c70
feat: sign and store router address
failfmi Apr 22, 2021
f97bda1
fix: transfer data check
failfmi Apr 23, 2021
c589521
fix: check if fee exists
failfmi Apr 23, 2021
b3ad373
e2e: add router address to expected transfer
failfmi Apr 23, 2021
8c45592
fix(transfer-data): nil return
failfmi Apr 23, 2021
f5ea498
feat(event): get hedera tx from id
failfmi Apr 23, 2021
562dfea
fix(recovery): add router address
failfmi Apr 26, 2021
6374ca0
Merge branch 'feature/transfer/store-sign-router-address' into featur…
failfmi Apr 26, 2021
6187e62
git: merge branch 'main' into feature/transfer/store-sign-router-address
failfmi Apr 27, 2021
af0e506
git: merge branch 'feature/transfer/store-sign-router-address' into f…
failfmi Apr 27, 2021
1568165
feat(contracts): update contract wrappers
failfmi Apr 27, 2021
f7b8db0
Merge branch 'feature/transfer/store-sign-router-address' into featur…
failfmi Apr 27, 2021
dda562d
git: Merge remote-tracking branch 'origin/main' into feature/events/g…
failfmi Apr 28, 2021
6f5d9df
git: Merge remote-tracking branch 'origin/main' into feature/transfer…
failfmi Apr 28, 2021
5cc459e
Merge branch 'feature/transfer/store-sign-router-address' into featur…
failfmi Apr 28, 2021
cceb8b4
refactor: clarify variable namings
failfmi Apr 28, 2021
13060c0
fix(e2e): add missing expected transfer check
failfmi Apr 28, 2021
0206a34
e2e(evm->hedera): validate event api call
failfmi Apr 28, 2021
0d2e627
Merge branch 'feature/transfer/store-sign-router-address' into featur…
failfmi Apr 28, 2021
b479935
e2e: clarify fatal error
failfmi Apr 28, 2021
7d3ddaa
fix(router): return 404 if not found
failfmi Apr 28, 2021
41f3657
Merge branch 'feature/transfer/store-sign-router-address' into featur…
failfmi Apr 28, 2021
17be4ff
fix(router-event): return 404 if not found
failfmi Apr 28, 2021
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
85 changes: 53 additions & 32 deletions app/clients/ethereum/contracts/router/router.go

Large diffs are not rendered by default.

85 changes: 84 additions & 1 deletion app/clients/ethereum/contracts/wtoken/wtoken.go

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions app/domain/service/burn-event.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,7 @@ type BurnEvent interface {
// ProcessEvent processes the burn event by submitting the appropriate
// scheduled transaction, leaving the synchronization of the actual transfer on HCS
ProcessEvent(event burn_event.BurnEvent)
// TransactionID returns the corresponding Scheduled Transaction paying out the
// fees to validators and the amount being bridged to the receiver address
TransactionID(id string) (string, error)
}
2 changes: 2 additions & 0 deletions app/domain/service/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import (

// Contracts interface is implemented by the Contracts Service providing business logic access to the Ethereum SmartContracts and other related utility functions
type Contracts interface {
// Address returns the address of the contract instance
Address() common.Address
// GetMembers returns the array of bridge members currently set in the Bridge contract
GetMembers() []string
// IsMember returns true/false depending on whether the provided address is a Bridge member or not
Expand Down
21 changes: 21 additions & 0 deletions app/domain/service/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright 2021 LimeChain Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package service

import "errors"

var ErrNotFound = errors.New("not found")
13 changes: 7 additions & 6 deletions app/domain/service/transfers.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ type Transfers interface {
}

type TransferData struct {
Recipient string `json:"recipient"`
Amount string `json:"amount"`
NativeAsset string `json:"nativeAsset"`
WrappedAsset string `json:"wrappedAsset"`
Signatures []string `json:"signatures"`
Majority bool `json:"majority"`
Recipient string `json:"recipient"`
RouterAddress string `json:"routerAddress"`
Amount string `json:"amount"`
NativeAsset string `json:"nativeAsset"`
WrappedAsset string `json:"wrappedAsset"`
Signatures []string `json:"signatures"`
Majority bool `json:"majority"`
}
7 changes: 5 additions & 2 deletions app/model/auth-message/auth-message.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (

// EncodeBytesFrom returns the array of bytes representing an
// authorisation signature ready to be signed by Ethereum Private Key
func EncodeBytesFrom(txId, wrappedAsset, receiverEthAddress, amount string) ([]byte, error) {
func EncodeBytesFrom(txId, routerAddress, wrappedAsset, receiverEthAddress, amount string) ([]byte, error) {
args, err := generateArguments()
if err != nil {
return nil, err
Expand All @@ -35,7 +35,7 @@ func EncodeBytesFrom(txId, wrappedAsset, receiverEthAddress, amount string) ([]b
return nil, err
}

bytesToHash, err := args.Pack([]byte(txId), common.HexToAddress(wrappedAsset), common.HexToAddress(receiverEthAddress), amountBn)
bytesToHash, err := args.Pack([]byte(txId), common.HexToAddress(routerAddress), common.HexToAddress(wrappedAsset), common.HexToAddress(receiverEthAddress), amountBn)
return keccak(bytesToHash), nil
}

Expand Down Expand Up @@ -65,6 +65,9 @@ func generateArguments() (abi.Arguments, error) {
{
Type: addressType,
},
{
Type: addressType,
},
{
Type: uint256Type,
}}, nil
Expand Down
13 changes: 7 additions & 6 deletions app/model/message/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,14 @@ func FromString(data, ts string) (*Message, error) {
}

// NewSignatureMessage instantiates Signature Message struct ready for submission to the Bridge Topic
func NewSignature(transferID, receiver, amount, signature, wrappedAsset string) *Message {
func NewSignature(transferID, routerAddress, receiver, amount, signature, wrappedAsset string) *Message {
topicMsg := &model.TopicEthSignatureMessage{
TransferID: transferID,
Receiver: receiver,
Amount: amount,
Signature: signature,
WrappedAsset: wrappedAsset,
TransferID: transferID,
RouterAddress: routerAddress,
Receiver: receiver,
Amount: amount,
Signature: signature,
WrappedAsset: wrappedAsset,
}
return &Message{topicMsg}
}
Expand Down
4 changes: 3 additions & 1 deletion app/model/transfer/transfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,17 @@ type Transfer struct {
Amount string
NativeAsset string
WrappedAsset string
RouterAddress string
}

// New instantiates Transfer struct ready for submission to the handler
func New(txId, receiver, nativeAsset, wrappedAsset, amount string) *Transfer {
func New(txId, receiver, nativeAsset, wrappedAsset, amount, routerAddress string) *Transfer {
return &Transfer{
TransactionId: txId,
Receiver: receiver,
Amount: amount,
NativeAsset: nativeAsset,
WrappedAsset: wrappedAsset,
RouterAddress: routerAddress,
}
}
3 changes: 2 additions & 1 deletion app/persistence/burn-event/burn-event.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,6 @@ func (sr Repository) Get(id string) (*entity.BurnEvent, error) {
}
return nil, result.Error
}

return burnEvent, nil
}
}
1 change: 1 addition & 0 deletions app/persistence/entity/transfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type Transfer struct {
NativeAsset string
WrappedAsset string
Amount string
RouterAddress string
Status string
SignatureMsgStatus string
Messages []Message `gorm:"foreignKey:TransferID"`
Expand Down
15 changes: 12 additions & 3 deletions app/persistence/transfer/transfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,21 @@ func (tr Repository) GetByTransactionId(txId string) (*entity.Transfer, error) {

func (tr Repository) GetWithPreloads(txId string) (*entity.Transfer, error) {
tx := &entity.Transfer{}
err := tr.dbClient.
result := tr.dbClient.
Preload("Fee").
Preload("Messages").
Model(entity.Transfer{}).
Where("transaction_id = ?", txId).
Find(tx).Error
return tx, err
Find(tx)

if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, result.Error
}

return tx, nil
}

// Returns Transfer with preloaded Fee table. Returns nil if not found
Expand Down Expand Up @@ -145,6 +153,7 @@ func (tr Repository) create(ct *model.Transfer, status string) (*entity.Transfer
Status: status,
NativeAsset: ct.NativeAsset,
WrappedAsset: ct.WrappedAsset,
RouterAddress: ct.RouterAddress,
}
err := tr.dbClient.Create(tx).Error

Expand Down
3 changes: 2 additions & 1 deletion app/process/recovery/recovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,8 @@ func (r Recovery) processUnfinishedOperations() error {
t.Receiver,
t.NativeAsset,
t.WrappedAsset,
t.Amount)
t.Amount,
r.contracts.Address().String())

err = r.transfers.ProcessTransfer(*transferMsg)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion app/process/watcher/transfer/watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ func (ctw Watcher) processTransaction(tx mirror_node.Transaction, q *pair.Queue)
return
}

transferMessage := transfer.New(tx.TransactionID, ethAddress, nativeAsset, wrappedAsset, amount)
transferMessage := transfer.New(tx.TransactionID, ethAddress, nativeAsset, wrappedAsset, amount, ctw.contractService.Address().String())
q.Push(&pair.Message{Payload: transferMessage})
}

Expand Down
46 changes: 46 additions & 0 deletions app/router/burn-event/burn-event.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package burn_event

import (
"fmt"
"github.com/go-chi/chi"
"github.com/go-chi/render"
"github.com/limechain/hedera-eth-bridge-validator/app/domain/service"
"github.com/limechain/hedera-eth-bridge-validator/app/router/response"
"github.com/limechain/hedera-eth-bridge-validator/config"
"net/http"
)

var (
Route = "/events"
logger = config.GetLoggerFor(fmt.Sprintf("Router [%s]", Route))
)

// GET: .../events/:id/tx
func getTxID(burnService service.BurnEvent) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
eventID := chi.URLParam(r, "id")

txID, err := burnService.TransactionID(eventID)
if err != nil {
logger.Errorf("Router resolved with an error. Error [%s].", err)
switch err {
case service.ErrNotFound:
render.Status(r, http.StatusNotFound)
render.JSON(w, r, response.ErrorResponse(err))
default:
render.Status(r, http.StatusInternalServerError)
render.JSON(w, r, response.ErrorResponse(response.ErrorInternalServerError))
}

return
}

render.JSON(w, r, txID)
failfmi marked this conversation as resolved.
Show resolved Hide resolved
}
}

func NewRouter(service service.BurnEvent) chi.Router {
r := chi.NewRouter()
r.Get("/{id}/tx", getTxID(service))
return r
}
12 changes: 9 additions & 3 deletions app/router/transfer/transfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,16 @@ func getTransfer(transfersService service.Transfers) func(w http.ResponseWriter,

transferData, err := transfersService.TransferData(transferID)
if err != nil {
render.Status(r, http.StatusInternalServerError)
render.JSON(w, r, response.ErrorResponse(response.ErrorInternalServerError))

logger.Errorf("Router resolved with an error. Error [%s].", err)
switch err {
case service.ErrNotFound:
render.Status(r, http.StatusNotFound)
render.JSON(w, r, response.ErrorResponse(err))
default:
render.Status(r, http.StatusInternalServerError)
render.JSON(w, r, response.ErrorResponse(response.ErrorInternalServerError))
}

return
}

Expand Down
16 changes: 16 additions & 0 deletions app/services/burn-event/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,22 @@ func (s *Service) prepareTransfers(event burn_event.BurnEvent) (recipientAmount
return remainder, validFee, transfers, nil
}

// TransactionID returns the corresponding Scheduled Transaction paying out the
// fees to validators and the amount being bridged to the receiver address
func (s *Service) TransactionID(id string) (string, error) {
event, err := s.repository.Get(id)
if err != nil {
s.logger.Errorf("[%s] - failed to get event.", id)
return "", err
}

if event == nil {
return "", service.ErrNotFound
}

return event.TransactionId.String, nil
}

func (s *Service) scheduledTxExecutionCallbacks(id string, feeAmount string) (onExecutionSuccess func(transactionID, scheduleID string), onExecutionFail func(transactionID string)) {
onExecutionSuccess = func(transactionID, scheduleID string) {
s.logger.Debugf("[%s] - Updating db status to Submitted with TransactionID [%s].",
Expand Down
3 changes: 2 additions & 1 deletion app/services/contracts/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ func (bsc *Service) ToNative(wrappedAsset common.Address) (string, error) {
return string(common.TrimRightZeroes(native)), nil
}

func (bsc *Service) GetBridgeContractAddress() common.Address {
// Address returns the address of the contract instance
func (bsc *Service) Address() common.Address {
return bsc.address
}

Expand Down
5 changes: 3 additions & 2 deletions app/services/messages/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ func (ss *Service) SanityCheckSignature(topicMessage message.Message) (bool, err
return false, err
}

match := t.Receiver == topicMessage.Receiver &&
match := topicMessage.Receiver == t.Receiver &&
topicMessage.RouterAddress == t.RouterAddress &&
topicMessage.Amount == signedAmount &&
topicMessage.WrappedAsset == wrappedAsset
return match, nil
Expand All @@ -115,7 +116,7 @@ func (ss *Service) SanityCheckSignature(topicMessage message.Message) (bool, err
// ProcessSignature processes the signature message, verifying and updating all necessary fields in the DB
func (ss *Service) ProcessSignature(tsm message.Message) error {
// Parse incoming message
authMsgBytes, err := auth_message.EncodeBytesFrom(tsm.TransferID, tsm.WrappedAsset, tsm.Receiver, tsm.Amount)
authMsgBytes, err := auth_message.EncodeBytesFrom(tsm.TransferID, tsm.RouterAddress, tsm.WrappedAsset, tsm.Receiver, tsm.Amount)
if err != nil {
ss.logger.Errorf("[%s] - Failed to encode the authorisation signature. Error: [%s]", tsm.TransferID, err)
return err
Expand Down
20 changes: 13 additions & 7 deletions app/services/transfers/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ func (ts *Service) InitiateNewTransfer(tm model.Transfer) (*entity.Transfer, err
func (ts *Service) SaveRecoveredTxn(txId, amount, nativeAsset, wrappedAsset string, memo string) error {
err := ts.transferRepository.SaveRecoveredTxn(&model.Transfer{
TransactionId: txId,
RouterAddress: ts.contractsService.Address().String(),
Receiver: memo,
Amount: amount,
NativeAsset: nativeAsset,
Expand Down Expand Up @@ -194,7 +195,7 @@ func (ts *Service) ProcessTransfer(tm model.Transfer) error {

wrappedAmount := strconv.FormatInt(remainder, 10)

authMsgHash, err := auth_message.EncodeBytesFrom(tm.TransactionId, tm.WrappedAsset, tm.Receiver, wrappedAmount)
authMsgHash, err := auth_message.EncodeBytesFrom(tm.TransactionId, tm.RouterAddress, tm.WrappedAsset, tm.Receiver, wrappedAmount)
if err != nil {
ts.logger.Errorf("[%s] - Failed to encode the authorisation signature. Error: [%s]", tm.TransactionId, err)
return err
Expand All @@ -209,6 +210,7 @@ func (ts *Service) ProcessTransfer(tm model.Transfer) error {

signatureMessage := message.NewSignature(
tm.TransactionId,
tm.RouterAddress,
tm.Receiver,
wrappedAmount,
signature,
Expand Down Expand Up @@ -329,6 +331,9 @@ func (ts *Service) TransferData(txId string) (service.TransferData, error) {
ts.logger.Errorf("[%s] - Failed to query Transfer with messages. Error: [%s].", txId, err)
return service.TransferData{}, err
}
if t == nil || t.Fee.Amount == "" {
return service.TransferData{}, service.ErrNotFound
}

amount, err := strconv.ParseInt(t.Amount, 10, 64)
if err != nil {
Expand All @@ -352,11 +357,12 @@ func (ts *Service) TransferData(txId string) (service.TransferData, error) {
reachedMajority := len(t.Messages) >= requiredSigCount

return service.TransferData{
Recipient: t.Receiver,
Amount: signedAmount,
NativeAsset: t.NativeAsset,
WrappedAsset: t.WrappedAsset,
Signatures: signatures,
Majority: reachedMajority,
Recipient: t.Receiver,
RouterAddress: t.RouterAddress,
Amount: signedAmount,
NativeAsset: t.NativeAsset,
WrappedAsset: t.WrappedAsset,
Signatures: signatures,
Majority: reachedMajority,
}, nil
}
2 changes: 2 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
cmw "github.com/limechain/hedera-eth-bridge-validator/app/process/watcher/message"
tw "github.com/limechain/hedera-eth-bridge-validator/app/process/watcher/transfer"
apirouter "github.com/limechain/hedera-eth-bridge-validator/app/router"
burn_event "github.com/limechain/hedera-eth-bridge-validator/app/router/burn-event"
"github.com/limechain/hedera-eth-bridge-validator/app/router/healthcheck"
"github.com/limechain/hedera-eth-bridge-validator/app/router/transfer"
"github.com/limechain/hedera-eth-bridge-validator/config"
Expand Down Expand Up @@ -103,6 +104,7 @@ func initializeAPIRouter(services *Services) *apirouter.APIRouter {
apiRouter := apirouter.NewAPIRouter()
apiRouter.AddV1Router(healthcheck.Route, healthcheck.NewRouter())
apiRouter.AddV1Router(transfer.Route, transfer.NewRouter(services.transfers))
apiRouter.AddV1Router(burn_event.Route, burn_event.NewRouter(services.burnEvents))
return apiRouter
}

Expand Down
Loading