@agoric/cosmos 0.34.2-dev-3c8aafe.0 → 0.34.2-dev-74fbe43.0.74fbe43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/Makefile +6 -2
  2. package/ante/ante.go +2 -2
  3. package/ante/inbound.go +1 -2
  4. package/ante/inbound_test.go +3 -1
  5. package/ante/vm_admission.go +1 -2
  6. package/app/app.go +256 -174
  7. package/app/encoding.go +6 -3
  8. package/app/export.go +50 -21
  9. package/app/genesis.go +7 -5
  10. package/app/params/encoding.go +1 -1
  11. package/app/params/proto.go +6 -4
  12. package/app/sim_test.go +11 -13
  13. package/app/txconfig/tx_config.go +169 -0
  14. package/app/upgrade.go +40 -90
  15. package/cmd/agd/agvm.go +1 -1
  16. package/cmd/agd/main.go +1 -1
  17. package/cmd/libdaemon/main.go +2 -2
  18. package/daemon/cmd/root.go +99 -30
  19. package/daemon/cmd/root_test.go +12 -27
  20. package/daemon/main.go +2 -9
  21. package/git-revision.txt +1 -1
  22. package/go.mod +130 -109
  23. package/go.sum +228 -469
  24. package/package.json +2 -2
  25. package/proto/agoric/swingset/msgs.proto +72 -9
  26. package/proto/agoric/swingset/swingset.proto +7 -2
  27. package/proto/agoric/vbank/vbank.proto +1 -1
  28. package/proto/agoric/vibc/msgs.proto +4 -0
  29. package/scripts/mockgen.sh +4 -0
  30. package/tests/e2e/vbank/vbank_test.go +172 -0
  31. package/tests/integrations/types/aminojson_test.go +214 -0
  32. package/tests/integrations/vbank/vbank_test.go +349 -0
  33. package/third_party/proto/amino/amino.proto +6 -1
  34. package/third_party/proto/cosmos/base/v1beta1/coin.proto +18 -5
  35. package/third_party/proto/cosmos/upgrade/v1beta1/upgrade.proto +4 -8
  36. package/third_party/proto/ibc/core/channel/v1/channel.proto +42 -17
  37. package/third_party/proto/ibc/core/client/v1/client.proto +48 -40
  38. package/types/address_hooks.go +2 -2
  39. package/types/address_hooks_test.go +3 -3
  40. package/types/ibc_packet.go +3 -3
  41. package/types/ibc_packet_test.go +3 -3
  42. package/types/kv_entry_helpers.go +3 -27
  43. package/types/kv_entry_helpers_test.go +2 -2
  44. package/types/legacy_address_encoder.go +58 -0
  45. package/vm/proto_json_test.go +1 -1
  46. package/vm/server.go +2 -1
  47. package/x/swingset/abci.go +2 -2
  48. package/x/swingset/client/cli/tx.go +16 -14
  49. package/x/swingset/config.go +1 -1
  50. package/x/swingset/genesis.go +2 -1
  51. package/x/swingset/handler.go +2 -1
  52. package/x/swingset/keeper/extension_snapshotter.go +14 -5
  53. package/x/swingset/keeper/extension_snapshotter_test.go +1 -1
  54. package/x/swingset/keeper/keeper.go +28 -23
  55. package/x/swingset/keeper/keeper_test.go +10 -7
  56. package/x/swingset/keeper/msg_server.go +52 -5
  57. package/x/swingset/keeper/msg_server_test.go +121 -0
  58. package/x/swingset/keeper/proposal.go +4 -0
  59. package/x/swingset/keeper/querier.go +1 -1
  60. package/x/swingset/keeper/swing_store_exports_handler.go +1 -1
  61. package/x/swingset/keeper/swing_store_exports_handler_test.go +1 -1
  62. package/x/swingset/keeper/test_utils.go +2 -2
  63. package/x/swingset/module.go +20 -22
  64. package/x/swingset/testing/queue.go +5 -2
  65. package/x/swingset/testutil/mocks.go +379 -0
  66. package/x/swingset/types/codec.go +10 -5
  67. package/x/swingset/types/default-params.go +13 -12
  68. package/x/swingset/types/expected_keepers.go +29 -4
  69. package/x/swingset/types/msgs.go +51 -36
  70. package/x/swingset/types/msgs.pb.go +561 -51
  71. package/x/swingset/types/params_test.go +21 -20
  72. package/x/swingset/types/swingset.pb.go +67 -61
  73. package/x/vbank/genesis.go +13 -9
  74. package/x/vbank/handler.go +2 -1
  75. package/x/vbank/keeper/grpc_query.go +4 -1
  76. package/x/vbank/keeper/keeper.go +108 -23
  77. package/x/vbank/keeper/querier.go +4 -1
  78. package/x/vbank/keeper/rewards.go +10 -5
  79. package/x/vbank/module.go +47 -75
  80. package/x/vbank/types/expected_keepers.go +15 -10
  81. package/x/vbank/types/key.go +3 -0
  82. package/x/vbank/types/params.go +4 -3
  83. package/x/vbank/types/vbank.pb.go +41 -40
  84. package/x/vbank/vbank.go +29 -11
  85. package/x/vbank/vbank_test.go +213 -154
  86. package/x/vibc/handler.go +2 -1
  87. package/x/vibc/keeper/keeper.go +10 -10
  88. package/x/vibc/keeper/migrations.go +1 -1
  89. package/x/vibc/keeper/triggers.go +1 -1
  90. package/x/vibc/module.go +5 -22
  91. package/x/vibc/types/codec.go +2 -1
  92. package/x/vibc/types/expected_keepers.go +7 -5
  93. package/x/vibc/types/ibc_module.go +5 -5
  94. package/x/vibc/types/msgs.go +30 -7
  95. package/x/vibc/types/msgs.pb.go +29 -25
  96. package/x/vibc/types/receiver.go +2 -2
  97. package/x/vlocalchain/handler.go +2 -1
  98. package/x/vlocalchain/keeper/keeper.go +17 -5
  99. package/x/vlocalchain/keeper/keeper_test.go +3 -2
  100. package/x/vlocalchain/types/expected_keepers.go +7 -4
  101. package/x/vlocalchain/vlocalchain_test.go +38 -26
  102. package/x/vstorage/genesis.go +10 -10
  103. package/x/vstorage/handler.go +2 -1
  104. package/x/vstorage/keeper/grpc_query.go +1 -1
  105. package/x/vstorage/keeper/keeper.go +72 -50
  106. package/x/vstorage/keeper/keeper_test.go +74 -54
  107. package/x/vstorage/keeper/querier.go +1 -1
  108. package/x/vstorage/module.go +27 -13
  109. package/x/vstorage/testing/queue.go +5 -3
  110. package/x/vstorage/vstorage.go +10 -9
  111. package/x/vstorage/vstorage_test.go +24 -18
  112. package/x/vtransfer/genesis.go +1 -3
  113. package/x/vtransfer/handler.go +3 -2
  114. package/x/vtransfer/ibc_middleware.go +5 -5
  115. package/x/vtransfer/ibc_middleware_test.go +43 -29
  116. package/x/vtransfer/keeper/keeper.go +35 -33
  117. package/x/vtransfer/module.go +8 -11
  118. package/x/vtransfer/types/expected_keepers.go +3 -3
  119. package/x/vtransfer/utils_test.go +26 -11
  120. package/daemon/cmd/testnet.go +0 -539
@@ -6,27 +6,28 @@ import (
6
6
  "encoding/json"
7
7
  "fmt"
8
8
 
9
+ corestore "cosmossdk.io/core/store"
10
+ sdkioerrors "cosmossdk.io/errors"
11
+ "cosmossdk.io/store/prefix"
12
+ storetypes "cosmossdk.io/store/types"
9
13
  "github.com/cosmos/cosmos-sdk/codec"
10
- "github.com/cosmos/cosmos-sdk/store/prefix"
11
- storetypes "github.com/cosmos/cosmos-sdk/store/types"
14
+ "github.com/cosmos/cosmos-sdk/runtime"
12
15
  sdk "github.com/cosmos/cosmos-sdk/types"
13
-
14
- sdkioerrors "cosmossdk.io/errors"
15
16
  sdktypeserrors "github.com/cosmos/cosmos-sdk/types/errors"
16
17
 
17
- capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper"
18
- capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
18
+ capabilitykeeper "github.com/cosmos/ibc-go/modules/capability/keeper"
19
+ capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types"
19
20
 
20
21
  agtypes "github.com/Agoric/agoric-sdk/golang/cosmos/types"
21
22
  "github.com/Agoric/agoric-sdk/golang/cosmos/vm"
22
23
  "github.com/Agoric/agoric-sdk/golang/cosmos/x/vibc"
23
24
  vibctypes "github.com/Agoric/agoric-sdk/golang/cosmos/x/vibc/types"
24
25
 
25
- clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"
26
- channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
27
- porttypes "github.com/cosmos/ibc-go/v7/modules/core/05-port/types"
28
- host "github.com/cosmos/ibc-go/v7/modules/core/24-host"
29
- ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported"
26
+ clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"
27
+ channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"
28
+ porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types"
29
+ host "github.com/cosmos/ibc-go/v8/modules/core/24-host"
30
+ ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported"
30
31
  )
31
32
 
32
33
  var _ porttypes.ICS4Wrapper = (*Keeper)(nil)
@@ -56,8 +57,8 @@ type Keeper struct {
56
57
 
57
58
  vibcKeeper vibc.Keeper
58
59
 
59
- key storetypes.StoreKey
60
- cdc codec.Codec
60
+ storeService corestore.KVStoreService
61
+ cdc codec.Codec
61
62
 
62
63
  vibcModule porttypes.IBCModule
63
64
 
@@ -137,7 +138,7 @@ func NewICS4Wrapper(k Keeper, down porttypes.ICS4Wrapper) *ics4Wrapper {
137
138
  // NewKeeper creates a new vtransfer Keeper instance
138
139
  func NewKeeper(
139
140
  cdc codec.Codec,
140
- key storetypes.StoreKey,
141
+ storeService corestore.KVStoreService,
141
142
  prototypeVibcKeeper vibc.Keeper,
142
143
  scopedTransferKeeper capabilitykeeper.ScopedKeeper,
143
144
  pushAction vm.ActionPusher,
@@ -150,10 +151,10 @@ func NewKeeper(
150
151
  k := Keeper{
151
152
  ReceiverImpl: vibcKeeper,
152
153
 
153
- vibcKeeper: vibcKeeper,
154
- key: key,
155
- vibcModule: vibc.NewIBCModule(vibcKeeper),
156
- cdc: cdc,
154
+ vibcKeeper: vibcKeeper,
155
+ storeService: storeService,
156
+ vibcModule: vibc.NewIBCModule(vibcKeeper),
157
+ cdc: cdc,
157
158
 
158
159
  debug: &KeeperDebugOptions{
159
160
  OverridePacket: nil,
@@ -208,7 +209,9 @@ func sequencePath(sequence uint64) string {
208
209
  func (k Keeper) PacketStore(ctx sdk.Context, ourOrigin agtypes.PacketOrigin, ourPort string, ourChannel string, sequence uint64) (storetypes.KVStore, []byte) {
209
210
  key := fmt.Sprintf("%s/%s/%s", ourOrigin, channelPath(ourPort, ourChannel), sequencePath(sequence))
210
211
  packetKey := []byte(key)
211
- return prefix.NewStore(ctx.KVStore(k.key), []byte(packetDataStoreKeyPrefix)), packetKey
212
+ kvstore := k.storeService.OpenKVStore(ctx)
213
+ store := runtime.KVStoreAdapter(kvstore)
214
+ return prefix.NewStore(store, []byte(packetDataStoreKeyPrefix)), packetKey
212
215
  }
213
216
 
214
217
  func (k Keeper) PacketStoreFromOrigin(ctx sdk.Context, ourOrigin agtypes.PacketOrigin, packet ibcexported.PacketI) (storetypes.KVStore, []byte) {
@@ -371,19 +374,20 @@ func (k Keeper) InterceptWriteAcknowledgement(ctx sdk.Context, chanCap *capabili
371
374
 
372
375
  // targetIsWatched checks if a target address has been watched by the VM.
373
376
  func (k Keeper) targetIsWatched(ctx sdk.Context, target string) bool {
374
- prefixStore := prefix.NewStore(
375
- ctx.KVStore(k.key),
376
- []byte(watchedAddressStoreKeyPrefix),
377
- )
377
+ kvstore := k.storeService.OpenKVStore(ctx)
378
+ store := runtime.KVStoreAdapter(kvstore)
379
+ prefixStore := prefix.NewStore(store, []byte(watchedAddressStoreKeyPrefix))
378
380
  return prefixStore.Has([]byte(target))
379
381
  }
380
382
 
381
383
  // GetWatchedAdresses returns the watched addresses from the keeper as a slice
382
384
  // of account addresses.
383
385
  func (k Keeper) GetWatchedAddresses(ctx sdk.Context) ([]sdk.AccAddress, error) {
386
+ kvstore := k.storeService.OpenKVStore(ctx)
387
+ store := runtime.KVStoreAdapter(kvstore)
384
388
  addresses := make([]sdk.AccAddress, 0)
385
- prefixStore := prefix.NewStore(ctx.KVStore(k.key), []byte(watchedAddressStoreKeyPrefix))
386
- iterator := sdk.KVStorePrefixIterator(prefixStore, []byte{})
389
+ prefixStore := prefix.NewStore(store, []byte(watchedAddressStoreKeyPrefix))
390
+ iterator := storetypes.KVStorePrefixIterator(prefixStore, []byte{})
387
391
  defer iterator.Close()
388
392
  for ; iterator.Valid(); iterator.Next() {
389
393
  addr, err := sdk.AccAddressFromBech32(string(iterator.Key()))
@@ -398,10 +402,9 @@ func (k Keeper) GetWatchedAddresses(ctx sdk.Context) ([]sdk.AccAddress, error) {
398
402
  // SetWatchedAddresses sets the watched addresses in the keeper from a slice of
399
403
  // SDK account addresses.
400
404
  func (k Keeper) SetWatchedAddresses(ctx sdk.Context, addresses []sdk.AccAddress) {
401
- prefixStore := prefix.NewStore(
402
- ctx.KVStore(k.key),
403
- []byte(watchedAddressStoreKeyPrefix),
404
- )
405
+ kvstore := k.storeService.OpenKVStore(ctx)
406
+ store := runtime.KVStoreAdapter(kvstore)
407
+ prefixStore := prefix.NewStore(store, []byte(watchedAddressStoreKeyPrefix))
405
408
  for _, addr := range addresses {
406
409
  prefixStore.Set([]byte(addr.String()), []byte(watchedAddressSentinel))
407
410
  }
@@ -420,10 +423,9 @@ func (k Keeper) Receive(cctx context.Context, jsonRequest string) (jsonReply str
420
423
  return "", err
421
424
  }
422
425
 
423
- prefixStore := prefix.NewStore(
424
- ctx.KVStore(k.key),
425
- []byte(watchedAddressStoreKeyPrefix),
426
- )
426
+ kvstore := k.storeService.OpenKVStore(ctx)
427
+ store := runtime.KVStoreAdapter(kvstore)
428
+ prefixStore := prefix.NewStore(store, []byte(watchedAddressStoreKeyPrefix))
427
429
  switch msg.Type {
428
430
  case "BRIDGE_TARGET_REGISTER":
429
431
  prefixStore.Set([]byte(msg.Target), []byte(watchedAddressSentinel))
@@ -12,7 +12,6 @@ import (
12
12
  cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
13
13
  "github.com/cosmos/cosmos-sdk/types/module"
14
14
 
15
- abci "github.com/cometbft/cometbft/abci/types"
16
15
  sdk "github.com/cosmos/cosmos-sdk/types"
17
16
  )
18
17
 
@@ -20,12 +19,18 @@ import (
20
19
  var (
21
20
  _ module.AppModule = AppModule{}
22
21
  _ module.AppModuleBasic = AppModuleBasic{}
22
+ _ module.HasGenesis = AppModule{}
23
23
  )
24
24
 
25
25
  // app module Basics object
26
26
  type AppModuleBasic struct {
27
27
  }
28
28
 
29
+ // IsAppModule implements the appmodule.AppModule interface.
30
+ func (am AppModule) IsAppModule() {}
31
+
32
+ // IsOnePerModuleType is a marker function just indicates that this is a one-per-module type.
33
+ func (am AppModule) IsOnePerModuleType() {}
29
34
  func (AppModuleBasic) Name() string {
30
35
  return ModuleName
31
36
  }
@@ -91,18 +96,10 @@ func (am AppModule) RegisterServices(cfg module.Configurator) {
91
96
 
92
97
  func (AppModule) ConsensusVersion() uint64 { return 1 }
93
98
 
94
- func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
95
- }
96
-
97
- func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate {
98
- // Prevent Cosmos SDK internal errors.
99
- return []abci.ValidatorUpdate{}
100
- }
101
-
102
- func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate {
99
+ func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) {
103
100
  var genesisState types.GenesisState
104
101
  cdc.MustUnmarshalJSON(data, &genesisState)
105
- return InitGenesis(ctx, am.keeper, &genesisState)
102
+ InitGenesis(ctx, am.keeper, &genesisState)
106
103
  }
107
104
 
108
105
  func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage {
@@ -2,9 +2,9 @@ package types
2
2
 
3
3
  import (
4
4
  sdk "github.com/cosmos/cosmos-sdk/types"
5
- capability "github.com/cosmos/cosmos-sdk/x/capability/types"
6
- channel "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
7
- ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported"
5
+ capability "github.com/cosmos/ibc-go/modules/capability/types"
6
+ channel "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"
7
+ ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported"
8
8
  )
9
9
 
10
10
  // ChannelKeeper defines the expected IBC channel keeper
@@ -1,19 +1,20 @@
1
1
  package vtransfer_test
2
2
 
3
3
  import (
4
+ "encoding/hex"
4
5
  "fmt"
5
6
  "strconv"
6
7
 
7
- sdk "github.com/cosmos/cosmos-sdk/types"
8
- clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"
9
- channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
10
- host "github.com/cosmos/ibc-go/v7/modules/core/24-host"
11
- ibctesting "github.com/cosmos/ibc-go/v7/testing"
8
+ abci "github.com/cometbft/cometbft/abci/types"
9
+ clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types"
10
+ channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"
11
+ host "github.com/cosmos/ibc-go/v8/modules/core/24-host"
12
+ ibctesting "github.com/cosmos/ibc-go/v8/testing"
12
13
  )
13
14
 
14
15
  // acknowledgePacketWithResult sends a MsgAcknowledgement to the channel associated with the endpoint.
15
16
  // [AGORIC] Would be nice to create a new ibctesting.AcknowledgePacketWithResult
16
- func acknowledgePacketWithResult(endpoint *ibctesting.Endpoint, packet channeltypes.Packet, ack []byte) (*sdk.Result, error) {
17
+ func acknowledgePacketWithResult(endpoint *ibctesting.Endpoint, packet channeltypes.Packet, ack []byte) (*abci.ExecTxResult, error) {
17
18
  // get proof of acknowledgement on counterparty
18
19
  packetKey := host.PacketAcknowledgementKey(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence())
19
20
  proof, proofHeight := endpoint.Counterparty.QueryProof(packetKey)
@@ -26,17 +27,24 @@ func acknowledgePacketWithResult(endpoint *ibctesting.Endpoint, packet channelty
26
27
  // ParseAckFromEvents parses events emitted from a MsgRecvPacket and returns the
27
28
  // acknowledgement.
28
29
  // [AGORIC] Signature taken from ibctesting.ParseAckFromEvents
29
- func ParseAckFromEvents(events sdk.Events) ([]byte, error) {
30
+ func ParseAckFromEvents(events []abci.Event) ([]byte, error) {
30
31
  return ParseAckFromFilteredEvents(events, channeltypes.EventTypeWriteAck)
31
32
  }
32
33
 
33
34
  // ParseAckFromFilteredEvents parses events emitted matching filteredType and returns the acknowledgement.
34
35
  // [AGORIC] Would be nice to improve the implementation and upstream it
35
- func ParseAckFromFilteredEvents(events sdk.Events, filteredType string) ([]byte, error) {
36
+ func ParseAckFromFilteredEvents(events []abci.Event, filteredType string) ([]byte, error) {
36
37
  for _, ev := range events {
37
38
  if ev.Type == filteredType {
38
39
  for _, attr := range ev.Attributes {
39
- if attr.Key == channeltypes.AttributeKeyAck { //nolint:staticcheck // DEPRECATED
40
+ switch attr.Key {
41
+ case channeltypes.AttributeKeyAckHex:
42
+ hexAck, err := hex.DecodeString(attr.Value)
43
+ if err != nil {
44
+ return nil, fmt.Errorf("failed to parse hex ack: %w", err)
45
+ }
46
+ return hexAck, nil
47
+ case channeltypes.AttributeKeyAck: //nolint:staticcheck // DEPRECATED
40
48
  return []byte(attr.Value), nil
41
49
  }
42
50
  }
@@ -48,18 +56,25 @@ func ParseAckFromFilteredEvents(events sdk.Events, filteredType string) ([]byte,
48
56
  // ParsePacketFromEvents parses the send_packet type events emitted by the IBC
49
57
  // module and returns the packet.
50
58
  // [AGORIC] Signature taken from ibctesting.ParsePacketFromEvents
51
- func ParsePacketFromEvents(events sdk.Events) (channeltypes.Packet, error) {
59
+ func ParsePacketFromEvents(events []abci.Event) (channeltypes.Packet, error) {
52
60
  return ParsePacketFromFilteredEvents(events, channeltypes.EventTypeSendPacket)
53
61
  }
54
62
 
55
63
  // ParsePacketFromFilteredEvents parses events emitted matching filteredType and returns the packet.
56
64
  // [AGORIC] Would be nice to improve the implementation and upstream it
57
- func ParsePacketFromFilteredEvents(events sdk.Events, filteredType string) (channeltypes.Packet, error) {
65
+ func ParsePacketFromFilteredEvents(events []abci.Event, filteredType string) (channeltypes.Packet, error) {
58
66
  for _, ev := range events {
59
67
  if ev.Type == filteredType {
60
68
  packet := channeltypes.Packet{}
61
69
  for _, attr := range ev.Attributes {
62
70
  switch attr.Key {
71
+ case channeltypes.AttributeKeyDataHex:
72
+ hexData, err := hex.DecodeString(attr.Value)
73
+ if err != nil {
74
+ return channeltypes.Packet{}, fmt.Errorf("failed to parse hex data: %w", err)
75
+ }
76
+ packet.Data = hexData
77
+
63
78
  case channeltypes.AttributeKeyData: //nolint:staticcheck // DEPRECATED
64
79
  packet.Data = []byte(attr.Value)
65
80