Skip to content

Commit

Permalink
[contract_indexer] fix transfer event handling (#3887)
Browse files Browse the repository at this point in the history
  • Loading branch information
envestcc authored Jun 15, 2023
1 parent a048de8 commit 4833da1
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 10 deletions.
12 changes: 10 additions & 2 deletions blockindex/contractstaking/event_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -429,12 +429,20 @@ func (eh *contractStakingEventHandler) handleTransferEvent(event eventParam) err
if err != nil {
return err
}
tokenID, err := event.IndexedFieldUint256("tokenId")
tokenIDParam, err := event.IndexedFieldUint256("tokenId")
if err != nil {
return err
}

eh.tokenOwner[tokenID.Uint64()] = to
tokenID := tokenIDParam.Uint64()
// cache token owner for stake event
eh.tokenOwner[tokenID] = to
// update bucket owner if token exists
if bi, ok := eh.dirty.getBucketInfo(tokenID); ok {
bi.Owner = to
return eh.dirty.updateBucketInfo(tokenID, bi)
}

return nil
}

Expand Down
35 changes: 27 additions & 8 deletions blockindex/contractstaking/indexer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ func TestContractStakingIndexerThreadSafe(t *testing.T) {
for i := 2; i < 1000; i++ {
height := uint64(i)
handler := newContractStakingEventHandler(indexer.cache, height)
stake(r, handler, owner, delegate, 1, 10, 100, height)
stake(r, handler, owner, delegate, int64(i), 10, 100, height)
err := indexer.commit(handler)
r.NoError(err)
}
Expand Down Expand Up @@ -293,6 +293,7 @@ func TestContractStakingIndexerBucketInfo(t *testing.T) {
owner := identityset.Address(0)
delegate := identityset.Address(1)
height++
createHeight := height
handler = newContractStakingEventHandler(indexer.cache, height)
stake(r, handler, owner, delegate, 1, 10, 100, height)
r.NoError(err)
Expand All @@ -312,6 +313,16 @@ func TestContractStakingIndexerBucketInfo(t *testing.T) {
r.EqualValues(10, indexer.CandidateVotes(delegate).Uint64())
r.EqualValues(1, indexer.TotalBucketCount())

// transfer
newOwner := identityset.Address(2)
height++
handler = newContractStakingEventHandler(indexer.cache, height)
transfer(r, handler, newOwner, int64(bucket.Index))
r.NoError(indexer.commit(handler))
bucket, ok = indexer.Bucket(bucket.Index)
r.True(ok)
r.EqualValues(newOwner, bucket.Owner)

// unlock
height++
handler = newContractStakingEventHandler(indexer.cache, height)
Expand All @@ -320,13 +331,13 @@ func TestContractStakingIndexerBucketInfo(t *testing.T) {
bucket, ok = indexer.Bucket(bucket.Index)
r.True(ok)
r.EqualValues(1, bucket.Index)
r.EqualValues(owner, bucket.Owner)
r.EqualValues(newOwner, bucket.Owner)
r.EqualValues(delegate, bucket.Candidate)
r.EqualValues(10, bucket.StakedAmount.Int64())
r.EqualValues(100, bucket.StakedDurationBlockNumber)
r.EqualValues(height, bucket.StakeStartBlockHeight)
r.False(bucket.AutoStake)
r.EqualValues(height-1, bucket.CreateBlockHeight)
r.EqualValues(createHeight, bucket.CreateBlockHeight)
r.EqualValues(maxBlockNumber, bucket.UnstakeStartBlockHeight)
r.EqualValues(_testStakingContractAddress, bucket.ContractAddress)
r.EqualValues(10, indexer.CandidateVotes(delegate).Uint64())
Expand All @@ -340,13 +351,13 @@ func TestContractStakingIndexerBucketInfo(t *testing.T) {
bucket, ok = indexer.Bucket(bucket.Index)
r.True(ok)
r.EqualValues(1, bucket.Index)
r.EqualValues(owner, bucket.Owner)
r.EqualValues(newOwner, bucket.Owner)
r.EqualValues(delegate, bucket.Candidate)
r.EqualValues(10, bucket.StakedAmount.Int64())
r.EqualValues(10, bucket.StakedDurationBlockNumber)
r.EqualValues(height-2, bucket.StakeStartBlockHeight)
r.EqualValues(createHeight, bucket.StakeStartBlockHeight)
r.True(bucket.AutoStake)
r.EqualValues(height-2, bucket.CreateBlockHeight)
r.EqualValues(createHeight, bucket.CreateBlockHeight)
r.EqualValues(maxBlockNumber, bucket.UnstakeStartBlockHeight)
r.EqualValues(_testStakingContractAddress, bucket.ContractAddress)
r.EqualValues(10, indexer.CandidateVotes(delegate).Uint64())
Expand All @@ -361,13 +372,13 @@ func TestContractStakingIndexerBucketInfo(t *testing.T) {
bucket, ok = indexer.Bucket(bucket.Index)
r.True(ok)
r.EqualValues(1, bucket.Index)
r.EqualValues(owner, bucket.Owner)
r.EqualValues(newOwner, bucket.Owner)
r.EqualValues(delegate, bucket.Candidate)
r.EqualValues(10, bucket.StakedAmount.Int64())
r.EqualValues(10, bucket.StakedDurationBlockNumber)
r.EqualValues(height, bucket.StakeStartBlockHeight)
r.False(bucket.AutoStake)
r.EqualValues(height-3, bucket.CreateBlockHeight)
r.EqualValues(createHeight, bucket.CreateBlockHeight)
r.EqualValues(height, bucket.UnstakeStartBlockHeight)
r.EqualValues(_testStakingContractAddress, bucket.ContractAddress)
r.EqualValues(0, indexer.CandidateVotes(delegate).Uint64())
Expand Down Expand Up @@ -611,3 +622,11 @@ func expandBucketType(r *require.Assertions, handler *contractStakingEventHandle
})
r.NoError(err)
}

func transfer(r *require.Assertions, handler *contractStakingEventHandler, owner address.Address, token int64) {
err := handler.handleTransferEvent(eventParam{
"to": common.BytesToAddress(owner.Bytes()),
"tokenId": big.NewInt(token),
})
r.NoError(err)
}
56 changes: 56 additions & 0 deletions e2etest/contract_staking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1715,6 +1715,62 @@ func TestContractStaking(t *testing.T) {
r.True(ok)
r.EqualValues(identityset.Address(delegateIdx).String(), bt.Candidate.String())
})

t.Run("transfer token", func(t *testing.T) {
t.Run("transferFrom", func(t *testing.T) {
delegateIdx := 5
bt := simpleStake(_delegates[delegateIdx], big.NewInt(10), big.NewInt(10))
tokenID := bt.Index
r.EqualValues(identityset.Address(delegateIdx).String(), bt.Candidate.String())
from := common.BytesToAddress(identityset.Address(_adminID).Bytes())
newOwnerIdx := 25
to := common.BytesToAddress(identityset.Address(newOwnerIdx).Bytes())
data, err := lsdABI.Pack("transferFrom", from, to, big.NewInt(int64(tokenID)))
r.NoError(err)
param = callParam{
contractAddr: contractAddresses,
bytecode: hex.EncodeToString(data),
amount: big.NewInt(0),
gasLimit: 1000000,
gasPrice: big.NewInt(0),
sk: identityset.PrivateKey(adminID),
}
receipts, _ = writeContract(bc, sf, dao, ap, []*callParam{&param}, r)
r.Len(receipts, 1)
r.EqualValues("", receipts[0].ExecutionRevertMsg())
r.EqualValues(iotextypes.ReceiptStatus_Success, receipts[0].Status)
bt, ok := indexer.Bucket(uint64(tokenID))
r.True(ok)
r.EqualValues(identityset.Address(newOwnerIdx).String(), bt.Owner.String())
})

t.Run("safeTransferFrom", func(t *testing.T) {
delegateIdx := 5
bt := simpleStake(_delegates[delegateIdx], big.NewInt(10), big.NewInt(10))
tokenID := bt.Index
r.EqualValues(identityset.Address(delegateIdx).String(), bt.Candidate.String())
from := common.BytesToAddress(identityset.Address(_adminID).Bytes())
newOwnerIdx := 25
to := common.BytesToAddress(identityset.Address(newOwnerIdx).Bytes())
data, err := lsdABI.Pack("safeTransferFrom", from, to, big.NewInt(int64(tokenID)))
r.NoError(err)
param = callParam{
contractAddr: contractAddresses,
bytecode: hex.EncodeToString(data),
amount: big.NewInt(0),
gasLimit: 1000000,
gasPrice: big.NewInt(0),
sk: identityset.PrivateKey(adminID),
}
receipts, _ = writeContract(bc, sf, dao, ap, []*callParam{&param}, r)
r.Len(receipts, 1)
r.EqualValues("", receipts[0].ExecutionRevertMsg())
r.EqualValues(iotextypes.ReceiptStatus_Success, receipts[0].Status)
bt, ok := indexer.Bucket(uint64(tokenID))
r.True(ok)
r.EqualValues(identityset.Address(newOwnerIdx).String(), bt.Owner.String())
})
})
}

func prepareContractStakingBlockchain(ctx context.Context, cfg config.Config, r *require.Assertions) (blockchain.Blockchain, factory.Factory, blockdao.BlockDAO, actpool.ActPool, *contractstaking.Indexer) {
Expand Down

0 comments on commit 4833da1

Please sign in to comment.