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

[action] add address and hash field in SealedEnvelope #3420

Merged
merged 10 commits into from
Jun 9, 2022
5 changes: 5 additions & 0 deletions action/action_deserializer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"encoding/hex"
"testing"

"github.com/iotexproject/go-pkgs/hash"
"github.com/iotexproject/iotex-proto/golang/iotextypes"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
Expand All @@ -34,8 +35,12 @@ func TestActionDeserializer(t *testing.T) {
r.Equal(_signByte, se.Signature())
r.Zero(se.Encoding())

// use valid signature and reset se.Hash
se.signature = _validSig
se.hash = hash.ZeroHash256
se.Hash()
Copy link
Collaborator

Choose a reason for hiding this comment

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

any validation for the return values?

se1, err := (&Deserializer{}).ActionToSealedEnvelope(se.Proto())
se1.Hash()
Copy link
Collaborator

Choose a reason for hiding this comment

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

same here

r.NoError(err)
r.Equal(se, se1)
}
Expand Down
24 changes: 24 additions & 0 deletions action/sealedenvelope.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/iotexproject/go-pkgs/crypto"
"github.com/iotexproject/go-pkgs/hash"
"github.com/iotexproject/iotex-address/address"
Copy link
Member

Choose a reason for hiding this comment

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

revert

Copy link
Contributor Author

Choose a reason for hiding this comment

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

reverted

"github.com/iotexproject/iotex-proto/golang/iotextypes"
"github.com/pkg/errors"
"go.uber.org/zap"
Expand All @@ -22,6 +23,8 @@ type SealedEnvelope struct {
evmNetworkID uint32
srcPubkey crypto.PublicKey
signature []byte
srcAddress address.Address
hash hash.Hash256
}

// envelopeHash returns the raw hash of embedded Envelope (this is the hash to be signed)
Expand All @@ -48,6 +51,17 @@ func (sealed *SealedEnvelope) envelopeHash() (hash.Hash256, error) {
// Hash returns the hash value of SealedEnvelope.
// an all-0 return value means the transaction is invalid
func (sealed *SealedEnvelope) Hash() (hash.Hash256, error) {
if sealed.hash == hash.ZeroHash256 {
hashVal, hashErr := sealed.calcHash()
if hashErr == nil {
sealed.hash = hashVal
}
return sealed.hash, hashErr
}
return sealed.hash, nil
}

func (sealed *SealedEnvelope) calcHash() (hash.Hash256, error) {
switch sealed.encoding {
case iotextypes.Encoding_ETHEREUM_RLP:
act, ok := sealed.Action().(EthCompatibleAction)
Expand All @@ -69,6 +83,14 @@ func (sealed *SealedEnvelope) Hash() (hash.Hash256, error) {
// SrcPubkey returns the source public key
func (sealed *SealedEnvelope) SrcPubkey() crypto.PublicKey { return sealed.srcPubkey }

// SenderAddress returns address of the source public key
func (sealed *SealedEnvelope) SenderAddress() address.Address {
if sealed.srcAddress == nil {
sealed.srcAddress = sealed.srcPubkey.Address()
}
return sealed.srcAddress
}

// Signature returns signature bytes
func (sealed *SealedEnvelope) Signature() []byte {
sig := make([]byte, len(sealed.signature))
Expand Down Expand Up @@ -141,6 +163,8 @@ func (sealed *SealedEnvelope) LoadProto(pbAct *iotextypes.Action) error {
sealed.signature = make([]byte, sigSize)
copy(sealed.signature, pbAct.GetSignature())
sealed.encoding = encoding
sealed.hash = hash.ZeroHash256
sealed.srcAddress = nil
return nil
}

Expand Down
10 changes: 7 additions & 3 deletions action/sealedenvelope_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,25 +156,29 @@ func TestSealedEnvelope_Proto(t *testing.T) {
req.Contains(se2.LoadProto(se.Proto()).Error(), v.err)
}

se.signature = _validSig
for _, v := range []struct {
enc iotextypes.Encoding
hash string
}{
{0, "0562e100b057804ee3cb4fa906a897852aa8075013a02ef1e229360f1e5ee339"},
{1, "d5dc789026c12cc69f1ea7997fbe0aa1bcc02e85176848c7b2ecf4da6b4560d0"},
} {
se, err = createSealedEnvelope(0)
se.signature = _validSig
se.encoding = v.enc
req.NoError(se2.LoadProto(se.Proto()))
if v.enc > 0 {
se.evmNetworkID = config.EVMNetworkID()
}
h, _ := se.Hash()
req.Equal(v.hash, hex.EncodeToString(h[:]))
se.SenderAddress()
_, _ = se2.Hash()
se2.SenderAddress()
req.Equal(se, se2)
tsf2, ok := se2.Envelope.Action().(*Transfer)
req.True(ok)
req.Equal(tsf, tsf2)
h, _ := se.Hash()
req.Equal(v.hash, hex.EncodeToString(h[:]))
}
}

Expand Down
14 changes: 12 additions & 2 deletions actpool/actpool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,12 @@ func TestActPool_GetUnconfirmedActs(t *testing.T) {
require.Equal([]action.SealedEnvelope(nil), acts)

acts = ap.GetUnconfirmedActs(_addr1)
require.Equal([]action.SealedEnvelope{tsf1, tsf3, tsf4, tsf5}, acts)
validated := []action.SealedEnvelope{tsf1, tsf3, tsf4, tsf5}
for i := range validated {
_, err = validated[i].Hash()
require.NoError(err)
}
require.Equal(validated, acts)
Copy link
Member

Choose a reason for hiding this comment

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

asserting hash

}

func TestActPool_GetActionByHash(t *testing.T) {
Expand Down Expand Up @@ -1089,7 +1094,12 @@ func TestActPool_SpeedUpAction(t *testing.T) {
appliedActionList = append(appliedActionList, bestAction)
}
// tsf1 is replaced by tsf3 with higher gas price
require.Equal(appliedActionList, []action.SealedEnvelope{tsf3, tsf2})
validated := []action.SealedEnvelope{tsf3, tsf2}
for i := range validated {
_, err = validated[i].Hash()
require.NoError(err)
}
require.Equal(appliedActionList, validated)
}

// Helper function to return the correct pending nonce just in case of empty queue
Expand Down
16 changes: 16 additions & 0 deletions blockchain/blockdao/blockdao_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,17 @@ func TestBlockDAO(t *testing.T) {
require.Equal(tipBlk.Height(), height)
blk, err := dao.GetBlock(hash)
require.NoError(err)
for idx := range blk.Actions {
_, err = blk.Actions[idx].Hash()
require.NoError(err)
}
require.Equal(tipBlk, blk)
blk, err = dao.GetBlockByHeight(height)
require.NoError(err)
for idx := range blk.Actions {
_, err = blk.Actions[idx].Hash()
require.NoError(err)
}
require.Equal(tipBlk, blk)
r, err := dao.GetReceipts(height)
require.NoError(err)
Expand Down Expand Up @@ -329,9 +337,17 @@ func TestBlockDAO(t *testing.T) {
require.Equal(tipHeight, height)
blk, err := dao.GetBlock(h)
require.NoError(err)
for idx := range blk.Actions {
_, err = blk.Actions[idx].Hash()
require.NoError(err)
}
require.Equal(tipBlk, blk)
blk, err = dao.GetBlockByHeight(height)
require.NoError(err)
for idx := range blk.Actions {
_, err = blk.Actions[idx].Hash()
require.NoError(err)
}
require.Equal(tipBlk, blk)

// test BlockDAO's API, 2nd loop to test LRU cache
Expand Down