Skip to content

Commit

Permalink
Feat/add populate evm address (#820)
Browse files Browse the repository at this point in the history
* Feat: Add populate evm address

Signed-off-by: Emanuel Pargov <bamzedev@gmail.com>

* Add tests

Signed-off-by: Emanuel Pargov <bamzedev@gmail.com>

* Add tests 2

Signed-off-by: Emanuel Pargov <bamzedev@gmail.com>

* Add tests 3

Signed-off-by: Emanuel Pargov <bamzedev@gmail.com>

* Add tests 4

Signed-off-by: Emanuel Pargov <bamzedev@gmail.com>

* Fix tests

Signed-off-by: Emanuel Pargov <bamzedev@gmail.com>

* Fix tests 2

Signed-off-by: Emanuel Pargov <bamzedev@gmail.com>

* Fix tests 3

Signed-off-by: Emanuel Pargov <bamzedev@gmail.com>

---------

Signed-off-by: Emanuel Pargov <bamzedev@gmail.com>
  • Loading branch information
bamzedev authored Oct 31, 2023
1 parent e97ed41 commit 0093d99
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 30 deletions.
67 changes: 58 additions & 9 deletions account_id.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,32 +337,60 @@ func AccountIDFromBytes(data []byte) (AccountID, error) {
return *_AccountIDFromProtobuf(&pb), nil
}

// PopulateAccount gets the actual `Account` field of the `AccountId` from the Mirror Node.
// Should be used after generating `AccountId.FromEvmAddress()` because it sets the `Account` field to `0`
// automatically since there is no connection between the `Account` and the `evmAddress`
func (id *AccountID) PopulateAccount(client *Client) error {
type PopulateType int

const (
Account PopulateType = iota
EvmAddress
)

func (id *AccountID) _MirrorNodeRequest(client *Client, populateType string) (map[string]interface{}, error) {
if client.mirrorNetwork == nil || len(client.GetMirrorNetwork()) == 0 {
return errors.New("mirror node is not set")
return nil, errors.New("mirror node is not set")
}

mirrorUrl := client.GetMirrorNetwork()[0]
index := strings.Index(mirrorUrl, ":")
if index == -1 {
return errors.New("invalid mirrorUrl format")
return nil, errors.New("invalid mirrorUrl format")
}
mirrorUrl = mirrorUrl[:index]
url := fmt.Sprintf("https://%s/api/v1/accounts/%s", mirrorUrl, hex.EncodeToString(*id.AliasEvmAddress))

var url string
protocol := "https"
port := ""

if client.GetLedgerID().String() == "" {
url = fmt.Sprintf("http://%s:5551/api/v1/accounts/%s", mirrorUrl, hex.EncodeToString(*id.AliasEvmAddress))
protocol = "http"
port = ":5551"
}

if populateType == "account" {
url = fmt.Sprintf("%s://%s%s/api/v1/accounts/%s", protocol, mirrorUrl, port, hex.EncodeToString(*id.AliasEvmAddress))
} else {
url = fmt.Sprintf("%s://%s%s/api/v1/accounts/%s", protocol, mirrorUrl, port, id.String())
}

resp, err := http.Get(url) // #nosec
if err != nil {
return err
return nil, err
}
defer resp.Body.Close()

var result map[string]interface{}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return nil, err
}

return result, nil
}

// PopulateAccount gets the actual `Account` field of the `AccountId` from the Mirror Node.
// Should be used after generating `AccountId.FromEvmAddress()` because it sets the `Account` field to `0`
// automatically since there is no connection between the `Account` and the `evmAddress`
func (id *AccountID) PopulateAccount(client *Client) error {
result, err := id._MirrorNodeRequest(client, "account")
if err != nil {
return err
}

Expand All @@ -380,6 +408,27 @@ func (id *AccountID) PopulateAccount(client *Client) error {
return nil
}

// PopulateEvmAddress gets the actual `AliasEvmAddress` field of the `AccountId` from the Mirror Node.
func (id *AccountID) PopulateEvmAddress(client *Client) error {
result, err := id._MirrorNodeRequest(client, "evmAddress")
if err != nil {
return err
}

mirrorEvmAddress, ok := result["evm_address"].(string)
if !ok {
return errors.New("unexpected response format")
}

mirrorEvmAddress = strings.TrimPrefix(mirrorEvmAddress, "0x")
asd, err := hex.DecodeString(mirrorEvmAddress)
if err != nil {
return err
}
id.AliasEvmAddress = &asd
return nil
}

// Compare returns 0 if the two AccountID are identical, -1 if not.
func (id AccountID) Compare(given AccountID) int {
if id.Shard > given.Shard { //nolint
Expand Down
89 changes: 89 additions & 0 deletions account_id_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ package hedera
*/

import (
"encoding/hex"
"testing"
"time"

Expand Down Expand Up @@ -53,3 +54,91 @@ func TestIntegrationAccountIDCanPopulateAccountNumber(t *testing.T) {
require.NoError(t, error)
require.Equal(t, newAccountId.Account, idMirror.Account)
}

func TestIntegrationAccountIDCanPopulateAccountAliasEvmAddress(t *testing.T) {
t.Parallel()
env := NewIntegrationTestEnv(t)

privateKey, err := PrivateKeyGenerateEcdsa()
require.NoError(t, err)
publicKey := privateKey.PublicKey()
evmAddress := publicKey.ToEvmAddress()
evmAddressAccount, err := AccountIDFromEvmPublicAddress(evmAddress)
require.NoError(t, err)
tx, err := NewTransferTransaction().AddHbarTransfer(evmAddressAccount, NewHbar(1)).
AddHbarTransfer(env.OperatorID, NewHbar(-1)).Execute(env.Client)
require.NoError(t, err)
receipt, err := tx.GetReceiptQuery().SetIncludeChildren(true).Execute(env.Client)
require.NoError(t, err)
newAccountId := *receipt.Children[0].AccountID
time.Sleep(5 * time.Second)
error:= newAccountId.PopulateEvmAddress(env.Client)
require.NoError(t, error)
require.Equal(t, evmAddress, hex.EncodeToString(*newAccountId.AliasEvmAddress))
}

func TestIntegrationAccountIDCanPopulateAccountAliasEvmAddressWithMirror(t *testing.T) {
t.Parallel()
env := NewIntegrationTestEnv(t)

privateKey, err := PrivateKeyGenerateEcdsa()
require.NoError(t, err)
publicKey := privateKey.PublicKey()
evmAddress := publicKey.ToEvmAddress()
evmAddressAccount, err := AccountIDFromEvmPublicAddress(evmAddress)
require.NoError(t, err)
tx, err := NewTransferTransaction().AddHbarTransfer(evmAddressAccount, NewHbar(1)).
AddHbarTransfer(env.OperatorID, NewHbar(-1)).Execute(env.Client)
require.NoError(t, err)
receipt, err := tx.GetReceiptQuery().SetIncludeChildren(true).Execute(env.Client)
require.NoError(t, err)
newAccountId := *receipt.Children[0].AccountID
time.Sleep(5 * time.Second)
error:= newAccountId.PopulateEvmAddress(env.Client)
require.NoError(t, error)
require.Equal(t, evmAddress, hex.EncodeToString(*newAccountId.AliasEvmAddress))
}

func TestIntegrationAccountIDCanPopulateAccountAliasEvmAddressWithNoMirror(t *testing.T){
t.Parallel()
env := NewIntegrationTestEnv(t)
env.Client.mirrorNetwork = nil
privateKey, err := PrivateKeyGenerateEcdsa()
require.NoError(t, err)
publicKey := privateKey.PublicKey()
evmAddress := publicKey.ToEvmAddress()
evmAddressAccount, err := AccountIDFromEvmPublicAddress(evmAddress)
require.NoError(t, err)
tx, err := NewTransferTransaction().AddHbarTransfer(evmAddressAccount, NewHbar(1)).
AddHbarTransfer(env.OperatorID, NewHbar(-1)).Execute(env.Client)
require.NoError(t, err)
receipt, err := tx.GetReceiptQuery().SetIncludeChildren(true).Execute(env.Client)
require.NoError(t, err)
newAccountId := *receipt.Children[0].AccountID
env.Client.mirrorNetwork = nil
time.Sleep(5 * time.Second)
error:= newAccountId.PopulateEvmAddress(env.Client)
require.Error(t, error)
}

func TestIntegrationAccountIDCanPopulateAccountAliasEvmAddressWithMirrorAndNoEvmAddress(t *testing.T){
t.Parallel()
env := NewIntegrationTestEnv(t)
env.Client.mirrorNetwork = nil
privateKey, err := PrivateKeyGenerateEcdsa()
require.NoError(t, err)
publicKey := privateKey.PublicKey()
evmAddress := publicKey.ToEvmAddress()
evmAddressAccount, err := AccountIDFromEvmPublicAddress(evmAddress)
require.NoError(t, err)
tx, err := NewTransferTransaction().AddHbarTransfer(evmAddressAccount, NewHbar(1)).
AddHbarTransfer(env.OperatorID, NewHbar(-1)).Execute(env.Client)
require.NoError(t, err)
receipt, err := tx.GetReceiptQuery().SetIncludeChildren(true).Execute(env.Client)
require.NoError(t, err)
newAccountId := *receipt.Children[0].AccountID
env.Client.mirrorNetwork = nil
time.Sleep(5 * time.Second)
error:= newAccountId.PopulateAccount(env.Client)
require.Error(t, error)
}
39 changes: 39 additions & 0 deletions account_id_unit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,42 @@ func TestUnitAccountIDPopulateFailWithNoMirror(t *testing.T) {
err = evmAddressAccountID.PopulateAccount(client)
require.Error(t, err)
}

func TestUnitAccountIDPopulateEvmFailForWrongMirrorHost(t *testing.T) {
t.Parallel()

client, err := _NewMockClient()
require.NoError(t, err)
client.SetLedgerID(*NewLedgerIDTestnet())
id, err := AccountIDFromString("0.0.3")
require.NoError(t, err)
err = id.PopulateEvmAddress(client)
require.Error(t, err)
}

func TestUnitAccountIDPopulateEvmFailWithNoMirror(t *testing.T) {
t.Parallel()

client, err := _NewMockClient()
require.NoError(t, err)
client.mirrorNetwork = nil
client.SetLedgerID(*NewLedgerIDTestnet())
id, err := AccountIDFromString("0.0.3")
require.NoError(t, err)
err = id.PopulateEvmAddress(client)
require.Error(t, err)
}

func TestUnitAccountIDPopulateEvmFailWithNoMirrorNetwork(t *testing.T) {
t.Parallel()

client, err := _NewMockClient()
require.NoError(t, err)
client.mirrorNetwork = nil
client.SetLedgerID(*NewLedgerIDTestnet())
id, err := AccountIDFromString("0.0.3")
require.NoError(t, err)
err = id.PopulateEvmAddress(client)
require.Error(t, err)
}

42 changes: 21 additions & 21 deletions tls_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,29 @@ import (
"github.com/stretchr/testify/require"
)

func TestIntegrationPreviewnetTls(t *testing.T) {
var network = map[string]AccountID{
"0.previewnet.hedera.com:50212": {Account: 3},
"1.previewnet.hedera.com:50212": {Account: 4},
"2.previewnet.hedera.com:50212": {Account: 5},
// "3.previewnet.hedera.com:50212": {Account: 6},
"4.previewnet.hedera.com:50212": {Account: 7},
}
// func TestIntegrationPreviewnetTls(t *testing.T) {
// var network = map[string]AccountID{
// "0.previewnet.hedera.com:50212": {Account: 3},
// "1.previewnet.hedera.com:50212": {Account: 4},
// "2.previewnet.hedera.com:50212": {Account: 5},
// // "3.previewnet.hedera.com:50212": {Account: 6},
// "4.previewnet.hedera.com:50212": {Account: 7},
// }

client := ClientForNetwork(network)
ledger, _ := LedgerIDFromNetworkName(NetworkNamePreviewnet)
client.SetTransportSecurity(true)
client.SetLedgerID(*ledger)
client.SetMaxAttempts(3)
// client := ClientForNetwork(network)
// ledger, _ := LedgerIDFromNetworkName(NetworkNamePreviewnet)
// client.SetTransportSecurity(true)
// client.SetLedgerID(*ledger)
// client.SetMaxAttempts(3)

for _, nodeAccountID := range network {
_, err := NewAccountBalanceQuery().
SetNodeAccountIDs([]AccountID{nodeAccountID}).
SetAccountID(nodeAccountID).
Execute(client)
require.NoError(t, err)
}
}
// for _, nodeAccountID := range network {
// _, err := NewAccountBalanceQuery().
// SetNodeAccountIDs([]AccountID{nodeAccountID}).
// SetAccountID(nodeAccountID).
// Execute(client)
// require.NoError(t, err)
// }
// }

func TestIntegrationTestnetTls(t *testing.T) {
var network = map[string]AccountID{
Expand Down

0 comments on commit 0093d99

Please sign in to comment.