From 6ff8d3bd539315be196e0769806c975f127e6ada Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Tue, 14 May 2024 14:26:25 +0200 Subject: [PATCH 01/15] feat(relay): submit constraints endpoint --- mev-boost-relay/services/api/constraints.go | 146 ++++++++++++++++++ mev-boost-relay/services/api/service.go | 90 ++++++++++- mev-boost-relay/services/api/service_test.go | 49 ++++++ mev-boost-relay/services/api/test_utils.go | 61 ++++++++ .../services/api/transaction_ssz.go | 52 +++++++ 5 files changed, 391 insertions(+), 7 deletions(-) create mode 100644 mev-boost-relay/services/api/constraints.go create mode 100644 mev-boost-relay/services/api/test_utils.go create mode 100644 mev-boost-relay/services/api/transaction_ssz.go diff --git a/mev-boost-relay/services/api/constraints.go b/mev-boost-relay/services/api/constraints.go new file mode 100644 index 00000000..94291524 --- /dev/null +++ b/mev-boost-relay/services/api/constraints.go @@ -0,0 +1,146 @@ +package api + +import ( + "encoding/hex" + "encoding/json" + "fmt" + "strings" + + "github.com/attestantio/go-eth2-client/spec/phase0" + "github.com/pkg/errors" +) + +type SignedConstraintSubmission struct { + Message *ConstraintSubmission + Signature phase0.BLSSignature `ssz-size:"96"` +} + +type signedConstraintSubmissionJSON struct { + Message *ConstraintSubmission `json:"message"` + Signature string `json:"signature"` +} + +func (s *SignedConstraintSubmission) MarshalJSON() ([]byte, error) { + return json.Marshal(&signedConstraintSubmissionJSON{ + Message: s.Message, + Signature: fmt.Sprintf("%#x", s.Signature), + }) +} + +func (s *SignedConstraintSubmission) UnmarshalJSON(input []byte) error { + var data signedConstraintSubmissionJSON + if err := json.Unmarshal(input, &data); err != nil { + return errors.Wrap(err, "invalid JSON") + } + + if data.Message == nil { + return errors.New("message missing") + } + + s.Message = data.Message + + if data.Signature == "" { + return errors.New("signature missing") + } + + signature, err := hex.DecodeString(strings.TrimPrefix(data.Signature, "0x")) + if err != nil { + return errors.Wrap(err, "invalid signature") + } + + if len(signature) != phase0.SignatureLength { + return errors.New("incorrect length for signature") + } + copy(s.Signature[:], signature) + + return nil +} + +type ConstraintSubmission struct { + RawTx Transaction `ssz-max:"1073741824"` + Slot uint64 + TxHash phase0.Hash32 `ssz-size:"32"` +} + +type constraintSubmissionJSON struct { + TxHash string `json:"txHash"` + RawTx string `json:"rawTx"` + Slot uint64 `json:"slot"` +} + +func (c *ConstraintSubmission) MarshalJSON() ([]byte, error) { + return json.Marshal(&constraintSubmissionJSON{ + Slot: c.Slot, + TxHash: c.TxHash.String(), + RawTx: fmt.Sprintf("%#x", c.RawTx), + }) +} + +func (c *ConstraintSubmission) UnmarshalJSON(input []byte) error { + var data constraintSubmissionJSON + if err := json.Unmarshal(input, &data); err != nil { + return err + } + + c.Slot = data.Slot + + txHash, err := hex.DecodeString((strings.TrimPrefix(data.TxHash, "0x"))) + if err != nil { + return errors.Wrap(err, "invalid tx hash") + } + + copy(c.TxHash[:], txHash) + + rawTx, err := hex.DecodeString((strings.TrimPrefix(data.RawTx, "0x"))) + if err != nil { + return errors.Wrap(err, "invalid raw tx") + } + + c.RawTx = rawTx + + return nil +} + +// Constraints is a map of constraints for a block. +type Constraints = map[phase0.Hash32]*Constraint + +// Constraint is a constraint on a block. For now just preconfirmations +// or inclusion constraints. +type Constraint struct { + RawTx Transaction `json:"rawTx"` +} + +// ConstraintCache is a cache for constraints. +type ConstraintCache struct { + // map of slots to constraints + constraints map[uint64]Constraints +} + +// NewConstraintCache creates a new constraint cache. +func NewConstraintCache() *ConstraintCache { + return &ConstraintCache{ + // TODO: there should be a maximum length here that we can pre-allocate (probably the lookahead window size) + constraints: make(map[uint64]Constraints), + } +} + +// AddInclusionConstraint adds an inclusion constraint to the cache at the given slot for the given transaction. +func (c *ConstraintCache) AddInclusionConstraint(slot uint64, txHash phase0.Hash32, rawTx Transaction) { + if _, exists := c.constraints[slot]; !exists { + c.constraints[slot] = make(map[phase0.Hash32]*Constraint) + } + + c.constraints[slot][txHash] = &Constraint{ + RawTx: rawTx, + } +} + +// Get gets the constraints at the given slot. +func (c *ConstraintCache) Get(slot uint64) Constraints { + return c.constraints[slot] +} + +// Delete deletes the constraints at the given slot. +func (c *ConstraintCache) Delete(slot uint64) { + delete(c.constraints, slot) +} diff --git a/mev-boost-relay/services/api/service.go b/mev-boost-relay/services/api/service.go index f836f480..baf67002 100644 --- a/mev-boost-relay/services/api/service.go +++ b/mev-boost-relay/services/api/service.go @@ -66,6 +66,8 @@ var ( // BOLT: this endpoint will return also ship preconfirmation proofs pathGetHeader = "/eth/v1/builder/header/{slot:[0-9]+}/{parent_hash:0x[a-fA-F0-9]+}/{pubkey:0x[a-fA-F0-9]+}" pathGetPayload = "/eth/v1/builder/blinded_blocks" + // BOLT: allow relay to receive constraints from the proposer + pathSubmitContraints = "/eth/v1/builder/constraints" // Block builder API pathBuilderGetValidators = "/relay/v1/builder/validators" @@ -186,6 +188,7 @@ type RelayAPI struct { redis *datastore.RedisCache memcached *datastore.Memcached db database.IDatabaseService + constraints *ConstraintCache headSlot uberatomic.Uint64 genesisInfo *beaconclient.GetGenesisResponse @@ -274,16 +277,18 @@ func NewRelayAPI(opts RelayAPIOpts) (api *RelayAPI, err error) { } api = &RelayAPI{ - opts: opts, - log: opts.Log, - boltLog: common.NewBoltLogger("RELAY"), - blsSk: opts.SecretKey, - publicKey: &publicKey, + opts: opts, + log: opts.Log, + boltLog: common.NewBoltLogger("RELAY"), + blsSk: opts.SecretKey, + publicKey: &publicKey, + datastore: opts.Datastore, beaconClient: opts.BeaconClient, redis: opts.Redis, memcached: opts.Memcached, db: opts.DB, + constraints: NewConstraintCache(), payloadAttributes: make(map[string]payloadAttributesHelper), @@ -345,6 +350,7 @@ func (api *RelayAPI) getRouter() http.Handler { r.HandleFunc(pathRegisterValidator, api.handleRegisterValidator).Methods(http.MethodPost) r.HandleFunc(pathGetHeader, api.handleGetHeader).Methods(http.MethodGet) r.HandleFunc(pathGetPayload, api.handleGetPayload).Methods(http.MethodPost) + r.HandleFunc(pathSubmitContraints, api.handleSubmitConstraints).Methods(http.MethodPost) } // Builder API @@ -1614,6 +1620,76 @@ func (api *RelayAPI) handleGetPayload(w http.ResponseWriter, req *http.Request) log.Info("execution payload delivered") } +func (api *RelayAPI) handleSubmitConstraints(w http.ResponseWriter, req *http.Request) { + ua := req.UserAgent() + headSlot := api.headSlot.Load() + receivedAt := time.Now().UTC() + log := api.log.WithFields(logrus.Fields{ + "method": "getPayload", + "ua": ua, + "mevBoostV": common.GetMevBoostVersionFromUserAgent(ua), + "contentLength": req.ContentLength, + "headSlot": headSlot, + "headSlotEpochPos": (headSlot % common.SlotsPerEpoch) + 1, + "idArg": req.URL.Query().Get("id"), + "timestampRequestStart": receivedAt.UnixMilli(), + }) + defer func() { + log.WithFields(logrus.Fields{ + "timestampRequestFin": time.Now().UTC().UnixMilli(), + "requestDurationMs": time.Since(receivedAt).Milliseconds(), + }).Info("request finished") + }() + + // Log at start and end of request + log.Info("request initiated") + + // Read the body first, so we can decode it later + body, err := io.ReadAll(req.Body) + if err != nil { + if strings.Contains(err.Error(), "i/o timeout") { + log.WithError(err).Error("getPayload request failed to decode (i/o timeout)") + api.RespondError(w, http.StatusInternalServerError, err.Error()) + return + } + + log.WithError(err).Error("could not read body of request from the beacon node") + api.RespondError(w, http.StatusBadRequest, err.Error()) + return + } + + // Decode payload + payload := new([]*SignedConstraintSubmission) + if err := json.NewDecoder(bytes.NewReader(body)).Decode(payload); err != nil { + log.WithError(err).Warn("failed to decode submit contraints body") + api.RespondError(w, http.StatusBadRequest, "failed to decode payload") + return + } + + if len(*payload) == 0 { + api.RespondError(w, http.StatusBadRequest, "No constraints submitted") + return + } + + // Add all constraints to the cache + for _, signedConstraint := range *payload { + constraint := signedConstraint.Message + + log.WithFields(logrus.Fields{ + "slot": constraint.Slot, + "txHash": constraint.TxHash.String(), + "rawTx": fmt.Sprintf("%#x", constraint.RawTx), + }).Info("[BOLT]: adding inclusion constraint to cache") + + // Add the constraint to the cache. They will be cleared when we receive a payload for the slot + // in `handleGetPayload` + api.constraints.AddInclusionConstraint(constraint.Slot, constraint.TxHash, constraint.RawTx) + } + + // respond to the HTTP request + api.RespondOK(w, nil) +} + // -------------------- // // BLOCK BUILDER APIS @@ -1817,8 +1893,8 @@ func (api *RelayAPI) updateRedisBid( opts redisUpdateBidOpts, proofs []*common.PreconfirmationWithProof) ( *datastore.SaveBidAndUpdateTopBidResponse, - *builderApi.VersionedSubmitBlindedBlockResponse, bool) { - + *builderApi.VersionedSubmitBlindedBlockResponse, bool, +) { api.boltLog.Infof("Updating Redis bid with proofs %v", proofs) // Prepare the response data diff --git a/mev-boost-relay/services/api/service_test.go b/mev-boost-relay/services/api/service_test.go index aaa9fcd9..5c1ce7c6 100644 --- a/mev-boost-relay/services/api/service_test.go +++ b/mev-boost-relay/services/api/service_test.go @@ -277,6 +277,55 @@ func TestGetHeader(t *testing.T) { require.Equal(t, http.StatusNoContent, rr.Code) } +func TestSubmitConstraints(t *testing.T) { + // Setup backend with headSlot and genesisTime + backend := newTestBackend(t, 1) + backend.relay.genesisInfo = &beaconclient.GetGenesisResponse{ + Data: beaconclient.GetGenesisResponseData{ + GenesisTime: uint64(time.Now().UTC().Unix()), + }, + } + + // request params + slot := uint64(2) + backend.relay.headSlot.Store(slot) + + // request path + path := "/eth/v1/builder/constraints" + + txHash := _HexToHash("0xba40436abdc8adc037e2c92ea1099a5849053510c3911037ff663085ce44bc49") + rawTx := _HexToBytes("0x02f871018304a5758085025ff11caf82565f94388c818ca8b9251b393131c08a736a67ccb1929787a41bb7ee22b41380c001a0c8630f734aba7acb4275a8f3b0ce831cf0c7c487fd49ee7bcca26ac622a28939a04c3745096fa0130a188fa249289fd9e60f9d6360854820dba22ae779ea6f573f") + + // Build the constraint + constraint := SignedConstraintSubmission{ + Message: &ConstraintSubmission{ + Slot: slot, + TxHash: txHash, + RawTx: rawTx, + }, + Signature: _HexToSignature( + "0x81510b571e22f89d1697545aac01c9ad0c1e7a3e778b3078bef524efae14990e58a6e960a152abd49de2e18d7fd3081c15d5c25867ccfad3d47beef6b39ac24b6b9fbf2cfa91c88f67aff750438a6841ec9e4a06a94ae41410c4f97b75ab284c"), + } + + payload := []SignedConstraintSubmission{constraint} + + t.Run("Constraints sent", func(t *testing.T) { + rr := backend.request(http.MethodPost, path, payload) + require.Equal(t, http.StatusOK, rr.Code) + + constraintCache := backend.relay.constraints + expected := constraintCache.Get(slot)[txHash] + actual := Constraint{RawTx: constraint.Message.RawTx} + + require.Equal(t, expected, &actual) + }) + + t.Run("Empty constraint list", func(t *testing.T) { + rr := backend.request(http.MethodPost, path, []SignedConstraintSubmission{}) + require.Equal(t, http.StatusBadRequest, rr.Code) + }) +} + func TestBuilderApiGetValidators(t *testing.T) { path := "/relay/v1/builder/validators" diff --git a/mev-boost-relay/services/api/test_utils.go b/mev-boost-relay/services/api/test_utils.go new file mode 100644 index 00000000..943ee1dc --- /dev/null +++ b/mev-boost-relay/services/api/test_utils.go @@ -0,0 +1,61 @@ +package api + +import ( + "github.com/attestantio/go-eth2-client/spec/bellatrix" + "github.com/attestantio/go-eth2-client/spec/phase0" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/flashbots/go-boost-utils/utils" + "github.com/sirupsen/logrus" +) + +// testLog is used to log information in the test methods +var testLog = logrus.NewEntry(logrus.New()) + +// _HexToBytes converts a hexadecimal string to a byte array +func _HexToBytes(hex string) []byte { + res, err := hexutil.Decode(hex) + if err != nil { + panic(err) + } + return res +} + +// _HexToHash converts a hexadecimal string to an Ethereum hash +func _HexToHash(s string) (ret phase0.Hash32) { + ret, err := utils.HexToHash(s) + if err != nil { + testLog.Error(err, " _HexToHash: ", s) + panic(err) + } + return ret +} + +// _HexToAddress converts a hexadecimal string to an Ethereum address +func _HexToAddress(s string) (ret bellatrix.ExecutionAddress) { + ret, err := utils.HexToAddress(s) + if err != nil { + testLog.Error(err, " _HexToAddress: ", s) + panic(err) + } + return ret +} + +// _HexToPubkey converts a hexadecimal string to a BLS Public Key +func _HexToPubkey(s string) (ret phase0.BLSPubKey) { + ret, err := utils.HexToPubkey(s) + if err != nil { + testLog.Error(err, " _HexToPubkey: ", s) + panic(err) + } + return +} + +// _HexToSignature converts a hexadecimal string to a BLS Signature +func _HexToSignature(s string) (ret phase0.BLSSignature) { + ret, err := utils.HexToSignature(s) + if err != nil { + testLog.Error(err, " _HexToSignature: ", s) + panic(err) + } + return +} diff --git a/mev-boost-relay/services/api/transaction_ssz.go b/mev-boost-relay/services/api/transaction_ssz.go new file mode 100644 index 00000000..2d98f450 --- /dev/null +++ b/mev-boost-relay/services/api/transaction_ssz.go @@ -0,0 +1,52 @@ +package api + +import ( + ssz "github.com/ferranbt/fastssz" +) + +// MaxBytesPerTransaction is the maximum length in bytes of a raw RLP-encoded transaction +var MaxBytesPerTransaction uint64 = 1_073_741_824 // 2**30 + +// Transaction is a wrapper type of byte slice to implement the ssz.HashRoot interface +type Transaction []byte + +// HashTreeRoot calculates the hash tree root of the transaction, which +// is a list of basic types (byte). +// +// Reference: https://github.com/ethereum/consensus-specs/blob/dev/ssz/simple-serialize.md#merkleization +func (tx *Transaction) HashTreeRoot() ([32]byte, error) { + hasher := ssz.NewHasher() + tx.HashTreeRootWith(hasher) + root, err := hasher.HashRoot() + + return root, err +} + +func (tx *Transaction) HashTreeRootWith(hh ssz.HashWalker) error { + var err error + byteLen := uint64(len(*tx)) + + if byteLen > MaxBytesPerTransaction { + err = ssz.ErrIncorrectListSize + return err + } + + // Load the bytes of the transaction into the hasher + hh.AppendBytes32(*tx) + // Perform `mix_in_length(merkleize(pack(value), limit=chunk_count(type)), len(value))` + // Reference: https://github.com/ethereum/consensus-specs/blob/dev/ssz/simple-serialize.md#merkleization + // + // The `indx` parameters is set to `0` as we need to consider the whole hh.buf buffer for this. + // In an implementation of more complex types, this parameter would be used to indicate the starting + // index of the buffer to be merkleized. It is used a single buffer to do everything for + // optimization purposes. + hh.MerkleizeWithMixin(0, byteLen, (1073741824+31)/32) + + return nil +} + +func (tx *Transaction) GetTree() (*ssz.Node, error) { + w := &ssz.Wrapper{} + tx.HashTreeRootWith(w) + return w.Node(), nil +} From 92ca29072e86d212a0862fadc5a5ce7c8ee763b2 Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Wed, 15 May 2024 11:28:51 +0200 Subject: [PATCH 02/15] refactor(relay): submit constraints endpoint --- mev-boost-relay/services/api/constraints.go | 28 ++++++++---- mev-boost-relay/services/api/service.go | 49 +++++++++++++++++++++ 2 files changed, 69 insertions(+), 8 deletions(-) diff --git a/mev-boost-relay/services/api/constraints.go b/mev-boost-relay/services/api/constraints.go index 94291524..810d12a3 100644 --- a/mev-boost-relay/services/api/constraints.go +++ b/mev-boost-relay/services/api/constraints.go @@ -11,19 +11,22 @@ import ( ) type SignedConstraintSubmission struct { - Message *ConstraintSubmission - Signature phase0.BLSSignature `ssz-size:"96"` + Message *ConstraintSubmission + Signature phase0.BLSSignature `ssz-size:"96"` + ProposerIndex uint64 } type signedConstraintSubmissionJSON struct { - Message *ConstraintSubmission `json:"message"` - Signature string `json:"signature"` + Message *ConstraintSubmission `json:"message"` + Signature string `json:"signature"` + ProposerIndex uint64 `json:"proposerIndex"` } func (s *SignedConstraintSubmission) MarshalJSON() ([]byte, error) { return json.Marshal(&signedConstraintSubmissionJSON{ - Message: s.Message, - Signature: fmt.Sprintf("%#x", s.Signature), + Message: s.Message, + Signature: fmt.Sprintf("%#x", s.Signature), + ProposerIndex: s.ProposerIndex, }) } @@ -38,6 +41,7 @@ func (s *SignedConstraintSubmission) UnmarshalJSON(input []byte) error { } s.Message = data.Message + s.ProposerIndex = data.ProposerIndex if data.Signature == "" { return errors.New("signature missing") @@ -57,15 +61,15 @@ func (s *SignedConstraintSubmission) UnmarshalJSON(input []byte) error { } type ConstraintSubmission struct { - RawTx Transaction `ssz-max:"1073741824"` Slot uint64 TxHash phase0.Hash32 `ssz-size:"32"` + RawTx Transaction `ssz-max:"1073741824"` } type constraintSubmissionJSON struct { + Slot uint64 `json:"slot"` TxHash string `json:"txHash"` RawTx string `json:"rawTx"` - Slot uint64 `json:"slot"` } func (c *ConstraintSubmission) MarshalJSON() ([]byte, error) { @@ -101,6 +105,14 @@ func (c *ConstraintSubmission) UnmarshalJSON(input []byte) error { return nil } +func (c *ConstraintSubmission) String() string { + data, err := json.Marshal(c) + if err != nil { + return fmt.Sprintf("ERR: %v", err) + } + return string(data) +} + // Constraints is a map of constraints for a block. type Constraints = map[phase0.Hash32]*Constraint diff --git a/mev-boost-relay/services/api/service.go b/mev-boost-relay/services/api/service.go index baf67002..1ea8e78a 100644 --- a/mev-boost-relay/services/api/service.go +++ b/mev-boost-relay/services/api/service.go @@ -1673,6 +1673,55 @@ func (api *RelayAPI) handleSubmitConstraints(w http.ResponseWriter, req *http.Re // Add all constraints to the cache for _, signedConstraint := range *payload { + // Retrieve proposer information + proposerIndex := signedConstraint.ProposerIndex + proposerPubKeyStr, found := api.datastore.GetKnownValidatorPubkeyByIndex(proposerIndex) + if !found { + log.Errorf("could not find proposer pubkey for index %d", proposerIndex) + api.RespondError(w, http.StatusBadRequest, "could not match proposer index to pubkey") + return + } + proposerPubKey, err := utils.HexToPubkey(proposerPubKeyStr.String()) + if err != nil { + log.WithError(err).Warn("could not convert pubkey to phase0.BLSPubKey") + api.RespondError(w, http.StatusBadRequest, "could not convert pubkey to phase0.BLSPubKey") + return + } + blsPublicKey, err := bls.PublicKeyFromBytes(proposerPubKey[:]) + if err != nil { + log.Errorf("could not convert proposer pubkey to bls.PublicKey: %v", err) + api.RespondError(w, http.StatusInternalServerError, "could not convert proposer pubkey to bls.PublicKey") + return + } + + // Verify signature + signatureBytes := []byte(signedConstraint.Signature[:]) + signature, err := bls.SignatureFromBytes(signatureBytes) + if err != nil { + log.Errorf("could not convert signature to bls.Signature: %v", err) + api.RespondError(w, http.StatusBadRequest, "Invalid raw BLS signature") + return + } + + // NOTE: Assuming this is what actually the proposer is signing + messageSigned, err := signedConstraint.Message.MarshalJSON() + if err != nil { + log.Errorf("could not marshal constraint message to json: %v", err) + api.RespondError(w, http.StatusInternalServerError, "could not marshal constraint message to json") + return + } + ok, err := bls.VerifySignature(signature, blsPublicKey, messageSigned) + if err != nil { + log.Errorf("error while veryfing signature: %v", err) + api.RespondError(w, http.StatusInternalServerError, "error while veryfing signature") + return + } + if !ok { + log.Error("Invalid BLS signature over constraint message") + api.RespondError(w, http.StatusBadRequest, fmt.Sprintf("Invalid BLS signature over constraint message %s", messageSigned)) + return + } + constraint := signedConstraint.Message log.WithFields(logrus.Fields{ From 254c8bb18ef32b2ccd883c7d37ff4b5caed8ed70 Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Wed, 15 May 2024 11:29:06 +0200 Subject: [PATCH 03/15] test(relay): submit constraints endpoint --- .../beaconclient/mock_multi_beacon_client.go | 36 +++++++++++++-- .../services/api/optimistic_test.go | 2 +- mev-boost-relay/services/api/service_test.go | 46 ++++++++++++++----- 3 files changed, 66 insertions(+), 18 deletions(-) diff --git a/mev-boost-relay/beaconclient/mock_multi_beacon_client.go b/mev-boost-relay/beaconclient/mock_multi_beacon_client.go index 5fdeb7fe..ef34edd9 100644 --- a/mev-boost-relay/beaconclient/mock_multi_beacon_client.go +++ b/mev-boost-relay/beaconclient/mock_multi_beacon_client.go @@ -3,12 +3,22 @@ package beaconclient import ( "github.com/attestantio/go-eth2-client/spec/capella" "github.com/flashbots/mev-boost-relay/common" + "github.com/sirupsen/logrus" + uberatomic "go.uber.org/atomic" ) -type MockMultiBeaconClient struct{} +type MockMultiBeaconClient struct { + log *logrus.Entry + bestBeaconIndex uberatomic.Int64 + beaconInstances []IBeaconInstance +} -func NewMockMultiBeaconClient() *MockMultiBeaconClient { - return &MockMultiBeaconClient{} +func NewMockMultiBeaconClient(log *logrus.Entry, beaconInstances []IBeaconInstance) *MockMultiBeaconClient { + return &MockMultiBeaconClient{ + log: log.WithField("component", "mockMultiBeaconClient"), + bestBeaconIndex: uberatomic.Int64{}, + beaconInstances: beaconInstances, + } } func (*MockMultiBeaconClient) BestSyncStatus() (*SyncStatusPayloadData, error) { @@ -20,8 +30,24 @@ func (*MockMultiBeaconClient) SubscribeToHeadEvents(slotC chan HeadEventData) {} func (*MockMultiBeaconClient) SubscribeToPayloadAttributesEvents(payloadAttrC chan PayloadAttributesEvent) { } -func (*MockMultiBeaconClient) GetStateValidators(stateID string) (*GetStateValidatorsResponse, error) { - return nil, nil +func (c *MockMultiBeaconClient) GetStateValidators(stateID string) (*GetStateValidatorsResponse, error) { + for i, client := range c.beaconInstances { + log := c.log.WithField("uri", client.GetURI()) + log.Debug("fetching validators") + + validators, err := client.GetStateValidators(stateID) + if err != nil { + log.WithError(err).Error("failed to fetch validators") + continue + } + + c.bestBeaconIndex.Store(int64(i)) + + // Received successful response. Set this index as last successful beacon node + return validators, nil + } + + return nil, ErrBeaconNodesUnavailable } func (*MockMultiBeaconClient) GetProposerDuties(epoch uint64) (*ProposerDutiesResponse, error) { diff --git a/mev-boost-relay/services/api/optimistic_test.go b/mev-boost-relay/services/api/optimistic_test.go index bb3a5eda..ed766b4e 100644 --- a/mev-boost-relay/services/api/optimistic_test.go +++ b/mev-boost-relay/services/api/optimistic_test.go @@ -90,7 +90,7 @@ func startTestBackend(t *testing.T) (*phase0.BLSPubKey, *bls.SecretKey, *testBac }, } backend.relay.opts.BlockBuilderAPI = true - backend.relay.beaconClient = beaconclient.NewMockMultiBeaconClient() + backend.relay.beaconClient = &beaconclient.MockMultiBeaconClient{} backend.relay.blockSimRateLimiter = &MockBlockSimulationRateLimiter{} backend.relay.blockBuildersCache = map[string]*blockBuilderCacheEntry{ pkStr: { diff --git a/mev-boost-relay/services/api/service_test.go b/mev-boost-relay/services/api/service_test.go index 5c1ce7c6..4bcf7e97 100644 --- a/mev-boost-relay/services/api/service_test.go +++ b/mev-boost-relay/services/api/service_test.go @@ -287,9 +287,31 @@ func TestSubmitConstraints(t *testing.T) { } // request params - slot := uint64(2) + slot := uint64(128) backend.relay.headSlot.Store(slot) + // Setup mocked beacon client for proposer + beaconClient := beaconclient.NewMockBeaconInstance() + + // Proposer data + proposerSecretKeyEC, proposerPublicKeyEC, err := bls.GenerateNewKeypair() + require.NoError(t, err) + proposerPublicKey, err := utils.BlsPublicKeyToPublicKey(proposerPublicKeyEC) + require.NoError(t, err) + proposerIndex := uint64(1) + mockValidatorEntry := beaconclient.ValidatorResponseEntry{ + Index: proposerIndex, Balance: "1000000", Validator: beaconclient.ValidatorResponseValidatorData{Pubkey: proposerPublicKey.String()}, + } + + // Update beacon client, create MultiBeaconClient and refresh validators in the datastore + beaconClient.AddValidator(mockValidatorEntry) + logger := logrus.New() + loggerEntry := logrus.NewEntry(logger) + + mockMultiBeaconClient := beaconclient.NewMockMultiBeaconClient(loggerEntry, []beaconclient.IBeaconInstance{beaconClient}) + + backend.relay.datastore.RefreshKnownValidators(backend.relay.log, mockMultiBeaconClient, slot) + // request path path := "/eth/v1/builder/constraints" @@ -297,17 +319,17 @@ func TestSubmitConstraints(t *testing.T) { rawTx := _HexToBytes("0x02f871018304a5758085025ff11caf82565f94388c818ca8b9251b393131c08a736a67ccb1929787a41bb7ee22b41380c001a0c8630f734aba7acb4275a8f3b0ce831cf0c7c487fd49ee7bcca26ac622a28939a04c3745096fa0130a188fa249289fd9e60f9d6360854820dba22ae779ea6f573f") // Build the constraint - constraint := SignedConstraintSubmission{ - Message: &ConstraintSubmission{ - Slot: slot, - TxHash: txHash, - RawTx: rawTx, - }, - Signature: _HexToSignature( - "0x81510b571e22f89d1697545aac01c9ad0c1e7a3e778b3078bef524efae14990e58a6e960a152abd49de2e18d7fd3081c15d5c25867ccfad3d47beef6b39ac24b6b9fbf2cfa91c88f67aff750438a6841ec9e4a06a94ae41410c4f97b75ab284c"), + constraintSubmission := ConstraintSubmission{ + Slot: slot, + TxHash: txHash, + RawTx: rawTx, } - - payload := []SignedConstraintSubmission{constraint} + constraintSubmissionJSON, err := constraintSubmission.MarshalJSON() + require.NoError(t, err) + signatureEC := bls.Sign(proposerSecretKeyEC, constraintSubmissionJSON) + constraintSignature := phase0.BLSSignature(bls.SignatureToBytes(signatureEC)[:]) + signedConstraintSubmission := SignedConstraintSubmission{Message: &constraintSubmission, Signature: constraintSignature, ProposerIndex: proposerIndex} + payload := []*SignedConstraintSubmission{&signedConstraintSubmission} t.Run("Constraints sent", func(t *testing.T) { rr := backend.request(http.MethodPost, path, payload) @@ -315,7 +337,7 @@ func TestSubmitConstraints(t *testing.T) { constraintCache := backend.relay.constraints expected := constraintCache.Get(slot)[txHash] - actual := Constraint{RawTx: constraint.Message.RawTx} + actual := Constraint{RawTx: constraintSubmission.RawTx} require.Equal(t, expected, &actual) }) From 6758febaaa58fd200c2018bbb54d410f147ddfe1 Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Wed, 15 May 2024 17:35:03 +0200 Subject: [PATCH 04/15] feat(relay): constraint sse wip; refactoring --- mev-boost-relay/services/api/service.go | 460 ++++++++++++++++++- mev-boost-relay/services/api/service_test.go | 3 + mev-boost-relay/services/api/utils.go | 6 + 3 files changed, 457 insertions(+), 12 deletions(-) diff --git a/mev-boost-relay/services/api/service.go b/mev-boost-relay/services/api/service.go index 1ea8e78a..76417fa5 100644 --- a/mev-boost-relay/services/api/service.go +++ b/mev-boost-relay/services/api/service.go @@ -74,6 +74,8 @@ var ( pathSubmitNewBlock = "/relay/v1/builder/blocks" // BOLT: allow builders to ship merkle proofs with their blocks pathSubmitNewBlockWithPreconfs = "/relay/v1/builder/blocks_with_preconfs" + // BOLT: allow builders to subscribe to constraints + pathSubscribeConstraints = "/relay/v1/builder/constraints/subscribe" // Data API pathDataProposerPayloadDelivered = "/relay/v1/data/bidtraces/proposer_payload_delivered" @@ -183,12 +185,17 @@ type RelayAPI struct { srvStarted uberatomic.Bool srvShutdown uberatomic.Bool - beaconClient beaconclient.IMultiBeaconClient - datastore *datastore.Datastore - redis *datastore.RedisCache - memcached *datastore.Memcached - db database.IDatabaseService - constraints *ConstraintCache + constraintsSse *http.Server + constraintsSseStarted uberatomic.Bool + constraintsSseShutdown uberatomic.Bool + + beaconClient beaconclient.IMultiBeaconClient + datastore *datastore.Datastore + redis *datastore.RedisCache + memcached *datastore.Memcached + db database.IDatabaseService + constraints *ConstraintCache + constraintsConsumers []chan *ConstraintSubmission headSlot uberatomic.Uint64 genesisInfo *beaconclient.GetGenesisResponse @@ -283,12 +290,13 @@ func NewRelayAPI(opts RelayAPIOpts) (api *RelayAPI, err error) { blsSk: opts.SecretKey, publicKey: &publicKey, - datastore: opts.Datastore, - beaconClient: opts.BeaconClient, - redis: opts.Redis, - memcached: opts.Memcached, - db: opts.DB, - constraints: NewConstraintCache(), + datastore: opts.Datastore, + beaconClient: opts.BeaconClient, + redis: opts.Redis, + memcached: opts.Memcached, + db: opts.DB, + constraints: NewConstraintCache(), + constraintsConsumers: make([]chan *ConstraintSubmission, 5), payloadAttributes: make(map[string]payloadAttributesHelper), @@ -506,6 +514,12 @@ func (api *RelayAPI) StartServer() (err error) { if errors.Is(err, http.ErrServerClosed) { return nil } + + err = api.constraintsSse.ListenAndServe() + if errors.Is(err, http.ErrServerClosed) { + return nil + } + return err } @@ -1730,8 +1744,11 @@ func (api *RelayAPI) handleSubmitConstraints(w http.ResponseWriter, req *http.Re "rawTx": fmt.Sprintf("%#x", constraint.RawTx), }).Info("[BOLT]: adding inclusion constraint to cache") + broadcastToChannels(api.constraintsConsumers, constraint) + // Add the constraint to the cache. They will be cleared when we receive a payload for the slot // in `handleGetPayload` + // TODO: actually do that. Alternative could be use a timer + go routine instead of modifying the getPayload call api.constraints.AddInclusionConstraint(constraint.Slot, constraint.TxHash, constraint.RawTx) } @@ -2384,6 +2401,425 @@ func (api *RelayAPI) handleSubmitNewBlock(w http.ResponseWriter, req *http.Reque w.WriteHeader(http.StatusOK) } +// TODO(bolt): We should check the preconfirmation proofs in this function to discard bids that are not valid. +// This is necessary to avoid the relay accept a high bid with invalid proofs, resulting in a missed opportunity +// for the proposer, who will refuse to sign the associated block header. +func (api *RelayAPI) handleSubmitNewBlockWithPreconfs(w http.ResponseWriter, req *http.Request) { + var pf common.Profile + var prevTime, nextTime time.Time + + headSlot := api.headSlot.Load() + receivedAt := time.Now().UTC() + prevTime = receivedAt + + args := req.URL.Query() + isCancellationEnabled := args.Get("cancellations") == "1" + + log := api.log.WithFields(logrus.Fields{ + "method": "submitNewBlockWithPreconfs", + "contentLength": req.ContentLength, + "headSlot": headSlot, + "cancellationEnabled": isCancellationEnabled, + "timestampRequestStart": receivedAt.UnixMilli(), + }) + + // Log at start and end of request + log.Info("request initiated") + defer func() { + log.WithFields(logrus.Fields{ + "timestampRequestFin": time.Now().UTC().UnixMilli(), + "requestDurationMs": time.Since(receivedAt).Milliseconds(), + }).Info("request finished") + }() + + // If cancellations are disabled but builder requested it, return error + if isCancellationEnabled && !api.ffEnableCancellations { + log.Info("builder submitted with cancellations enabled, but feature flag is disabled") + api.RespondError(w, http.StatusBadRequest, "cancellations are disabled") + return + } + + var err error + var reader io.Reader = req.Body + isGzip := req.Header.Get("Content-Encoding") == "gzip" + log = log.WithField("reqIsGzip", isGzip) + if isGzip { + reader, err = gzip.NewReader(req.Body) + if err != nil { + log.WithError(err).Warn("could not create gzip reader") + api.RespondError(w, http.StatusBadRequest, err.Error()) + return + } + } + + limitReader := io.LimitReader(reader, 10*1024*1024) // 10 MB + requestPayloadBytes, err := io.ReadAll(limitReader) + if err != nil { + log.WithError(err).Warn("could not read payload") + api.RespondError(w, http.StatusBadRequest, err.Error()) + return + } + + nextTime = time.Now().UTC() + pf.PayloadLoad = uint64(nextTime.Sub(prevTime).Microseconds()) + prevTime = nextTime + + // BOLT: new payload type + payload := new(common.VersionedSubmitBlockRequestWithPreconfsProofs) + + // Check for SSZ encoding + contentType := req.Header.Get("Content-Type") + if contentType == "application/octet-stream" { + // TODO-BOLT: implement SSZ decoding + panic("SSZ decoding not implemented for preconfs yet") + } else { + log = log.WithField("reqContentType", "json") + if err := json.Unmarshal(requestPayloadBytes, payload); err != nil { + api.boltLog.WithError(err).Warn("Could not decode payload - JSON") + api.RespondError(w, http.StatusBadRequest, err.Error()) + return + } + } + + num, _ := payload.Inner.BlockNumber() + bhash, _ := payload.Inner.BlockHash() + api.boltLog.Infof("Got decoded payload from builder: \nPayload: %v\nBlock hash: %s\nBlockNum: %d\n", payload.Inner.String(), bhash, num) + api.boltLog.Infof("Headslot: %d\n", headSlot) + + nextTime = time.Now().UTC() + pf.Decode = uint64(nextTime.Sub(prevTime).Microseconds()) + prevTime = nextTime + + isLargeRequest := len(requestPayloadBytes) > fastTrackPayloadSizeLimit + // getting block submission info also validates bid trace and execution submission are not empty + submission, err := common.GetBlockSubmissionInfo(payload.Inner) + if err != nil { + log.WithError(err).Warn("missing fields in submit block request") + api.RespondError(w, http.StatusBadRequest, err.Error()) + return + } + log = log.WithFields(logrus.Fields{ + "timestampAfterDecoding": time.Now().UTC().UnixMilli(), + "slot": submission.BidTrace.Slot, + "builderPubkey": submission.BidTrace.BuilderPubkey.String(), + "blockHash": submission.BidTrace.BlockHash.String(), + "proposerPubkey": submission.BidTrace.ProposerPubkey.String(), + "parentHash": submission.BidTrace.ParentHash.String(), + "value": submission.BidTrace.Value.Dec(), + "numTx": len(submission.Transactions), + "payloadBytes": len(requestPayloadBytes), + "isLargeRequest": isLargeRequest, + }) + // deneb specific logging + if payload.Inner.Deneb != nil { + log = log.WithFields(logrus.Fields{ + "numBlobs": len(payload.Inner.Deneb.BlobsBundle.Blobs), + "blobGasUsed": payload.Inner.Deneb.ExecutionPayload.BlobGasUsed, + "excessBlobGas": payload.Inner.Deneb.ExecutionPayload.ExcessBlobGas, + }) + } + + ok := api.checkSubmissionSlotDetails(w, log, headSlot, payload.Inner, submission) + if !ok { + return + } + + builderPubkey := submission.BidTrace.BuilderPubkey + builderEntry, ok := api.checkBuilderEntry(w, log, builderPubkey) + if !ok { + return + } + + log = log.WithField("builderIsHighPrio", builderEntry.status.IsHighPrio) + + gasLimit, ok := api.checkSubmissionFeeRecipient(w, log, submission.BidTrace) + if !ok { + return + } + + // Don't accept blocks with 0 value + if submission.BidTrace.Value.ToBig().Cmp(ZeroU256.BigInt()) == 0 || len(submission.Transactions) == 0 { + log.Info("submitNewBlock failed: block with 0 value or no txs") + w.WriteHeader(http.StatusOK) + return + } + + // Sanity check the submission + err = SanityCheckBuilderBlockSubmission(payload.Inner) + if err != nil { + log.WithError(err).Info("block submission sanity checks failed") + api.RespondError(w, http.StatusBadRequest, err.Error()) + return + } + + attrs, ok := api.checkSubmissionPayloadAttrs(w, log, submission) + if !ok { + return + } + + // Verify the signature + log = log.WithField("timestampBeforeSignatureCheck", time.Now().UTC().UnixMilli()) + signature := submission.Signature + ok, err = ssz.VerifySignature(submission.BidTrace, api.opts.EthNetDetails.DomainBuilder, builderPubkey[:], signature[:]) + log = log.WithField("timestampAfterSignatureCheck", time.Now().UTC().UnixMilli()) + if err != nil { + log.WithError(err).Warn("failed verifying builder signature") + api.RespondError(w, http.StatusBadRequest, "failed verifying builder signature") + return + } else if !ok { + log.Warn("invalid builder signature") + api.RespondError(w, http.StatusBadRequest, "invalid signature") + return + } + + log = log.WithField("timestampBeforeCheckingFloorBid", time.Now().UTC().UnixMilli()) + + // Create the redis pipeline tx + tx := api.redis.NewTxPipeline() + + // channel to send simulation result to the deferred function + simResultC := make(chan *blockSimResult, 1) + var eligibleAt time.Time // will be set once the bid is ready + + submission, err = common.GetBlockSubmissionInfo(payload.Inner) + if err != nil { + log.WithError(err).Warn("missing fields in submit block request") + api.RespondError(w, http.StatusBadRequest, err.Error()) + return + } + + bfOpts := bidFloorOpts{ + w: w, + tx: tx, + log: log, + cancellationsEnabled: isCancellationEnabled, + simResultC: simResultC, + submission: submission, + } + floorBidValue, ok := api.checkFloorBidValue(bfOpts) + if !ok { + return + } + + log = log.WithField("timestampAfterCheckingFloorBid", time.Now().UTC().UnixMilli()) + + // Deferred saving of the builder submission to database (whenever this function ends) + defer func() { + savePayloadToDatabase := !api.ffDisablePayloadDBStorage + var simResult *blockSimResult + select { + case simResult = <-simResultC: + case <-time.After(10 * time.Second): + log.Warn("timed out waiting for simulation result") + simResult = &blockSimResult{false, false, nil, nil} + } + + submissionEntry, err := api.db.SaveBuilderBlockSubmission( + payload.Inner, + simResult.requestErr, + simResult.validationErr, + receivedAt, + eligibleAt, + simResult.wasSimulated, + savePayloadToDatabase, + pf, + simResult.optimisticSubmission, + payload.Proofs, // BOLT: add merkle proofs to the submission + ) + if err != nil { + log.WithError(err).WithField("payload", payload).Error("saving builder block submission to database failed") + return + } + + err = api.db.UpsertBlockBuilderEntryAfterSubmission(submissionEntry, simResult.validationErr != nil) + if err != nil { + log.WithError(err).Error("failed to upsert block-builder-entry") + } + }() + + // --------------------------------- + // THE BID WILL BE SIMULATED SHORTLY + // --------------------------------- + + log = log.WithField("timestampBeforeCheckingTopBid", time.Now().UTC().UnixMilli()) + + // Get the latest top bid value from Redis + bidIsTopBid := false + topBidValue, err := api.redis.GetTopBidValue(context.Background(), tx, submission.BidTrace.Slot, submission.BidTrace.ParentHash.String(), submission.BidTrace.ProposerPubkey.String()) + if err != nil { + log.WithError(err).Error("failed to get top bid value from redis") + } else { + bidIsTopBid = submission.BidTrace.Value.ToBig().Cmp(topBidValue) == 1 + log = log.WithFields(logrus.Fields{ + "topBidValue": topBidValue.String(), + "newBidIsTopBid": bidIsTopBid, + }) + } + + log = log.WithField("timestampAfterCheckingTopBid", time.Now().UTC().UnixMilli()) + + nextTime = time.Now().UTC() + pf.Prechecks = uint64(nextTime.Sub(prevTime).Microseconds()) + prevTime = nextTime + + // Simulate the block submission and save to db + fastTrackValidation := builderEntry.status.IsHighPrio && bidIsTopBid && !isLargeRequest + timeBeforeValidation := time.Now().UTC() + + log = log.WithFields(logrus.Fields{ + "timestampBeforeValidation": timeBeforeValidation.UTC().UnixMilli(), + "fastTrackValidation": fastTrackValidation, + }) + + // Construct simulation request + opts := blockSimOptions{ + isHighPrio: builderEntry.status.IsHighPrio, + fastTrack: fastTrackValidation, + log: log, + builder: builderEntry, + req: &common.BuilderBlockValidationRequest{ + VersionedSubmitBlockRequest: payload.Inner, + RegisteredGasLimit: gasLimit, + ParentBeaconBlockRoot: attrs.parentBeaconRoot, + }, + } + // With sufficient collateral, process the block optimistically. + if builderEntry.status.IsOptimistic && + builderEntry.collateral.Cmp(submission.BidTrace.Value.ToBig()) >= 0 && + submission.BidTrace.Slot == api.optimisticSlot.Load() { + go api.processOptimisticBlock(opts, simResultC) + } else { + // Simulate block (synchronously). + requestErr, validationErr := api.simulateBlock(context.Background(), opts) // success/error logging happens inside + simResultC <- &blockSimResult{requestErr == nil, false, requestErr, validationErr} + validationDurationMs := time.Since(timeBeforeValidation).Milliseconds() + log = log.WithFields(logrus.Fields{ + "timestampAfterValidation": time.Now().UTC().UnixMilli(), + "validationDurationMs": validationDurationMs, + }) + if requestErr != nil { // Request error + if os.IsTimeout(requestErr) { + api.RespondError(w, http.StatusGatewayTimeout, "validation request timeout") + } else { + api.RespondError(w, http.StatusBadRequest, requestErr.Error()) + } + return + } else { + if validationErr != nil { + api.RespondError(w, http.StatusBadRequest, validationErr.Error()) + return + } + } + } + + nextTime = time.Now().UTC() + pf.Simulation = uint64(nextTime.Sub(prevTime).Microseconds()) + prevTime = nextTime + + // If cancellations are enabled, then abort now if this submission is not the latest one + if isCancellationEnabled { + // Ensure this request is still the latest one. This logic intentionally ignores the value of the bids and makes the current active bid the one + // that arrived at the relay last. This allows for builders to reduce the value of their bid (effectively cancel a high bid) by ensuring a lower + // bid arrives later. Even if the higher bid takes longer to simulate, by checking the receivedAt timestamp, this logic ensures that the low bid + // is not overwritten by the high bid. + // + // NOTE: this can lead to a rather tricky race condition. If a builder submits two blocks to the relay concurrently, then the randomness of network + // latency will make it impossible to predict which arrives first. Thus a high bid could unintentionally be overwritten by a low bid that happened + // to arrive a few microseconds later. If builders are submitting blocks at a frequency where they cannot reliably predict which bid will arrive at + // the relay first, they should instead use multiple pubkeys to avoid uninitentionally overwriting their own bids. + latestPayloadReceivedAt, err := api.redis.GetBuilderLatestPayloadReceivedAt(context.Background(), tx, submission.BidTrace.Slot, submission.BidTrace.BuilderPubkey.String(), submission.BidTrace.ParentHash.String(), submission.BidTrace.ProposerPubkey.String()) + if err != nil { + log.WithError(err).Error("failed getting latest payload receivedAt from redis") + } else if receivedAt.UnixMilli() < latestPayloadReceivedAt { + log.Infof("already have a newer payload: now=%d / prev=%d", receivedAt.UnixMilli(), latestPayloadReceivedAt) + api.RespondError(w, http.StatusBadRequest, "already using a newer payload") + return + } + } + redisOpts := redisUpdateBidOpts{ + w: w, + tx: tx, + log: log, + cancellationsEnabled: isCancellationEnabled, + receivedAt: receivedAt, + floorBidValue: floorBidValue, + payload: payload.Inner, + } + updateBidResult, getPayloadResponse, ok := api.updateRedisBid(redisOpts, payload.Proofs) + if !ok { + return + } + + // Add fields to logs + log = log.WithFields(logrus.Fields{ + "timestampAfterBidUpdate": time.Now().UTC().UnixMilli(), + "wasBidSavedInRedis": updateBidResult.WasBidSaved, + "wasTopBidUpdated": updateBidResult.WasTopBidUpdated, + "topBidValue": updateBidResult.TopBidValue, + "prevTopBidValue": updateBidResult.PrevTopBidValue, + "profileRedisSavePayloadUs": updateBidResult.TimeSavePayload.Microseconds(), + "profileRedisUpdateTopBidUs": updateBidResult.TimeUpdateTopBid.Microseconds(), + "profileRedisUpdateFloorUs": updateBidResult.TimeUpdateFloor.Microseconds(), + }) + + if updateBidResult.WasBidSaved { + // Bid is eligible to win the auction + eligibleAt = time.Now().UTC() + log = log.WithField("timestampEligibleAt", eligibleAt.UnixMilli()) + + // Save to memcache in the background + if api.memcached != nil { + go func() { + err = api.memcached.SaveExecutionPayload(submission.BidTrace.Slot, submission.BidTrace.ProposerPubkey.String(), submission.BidTrace.BlockHash.String(), getPayloadResponse) + if err != nil { + log.WithError(err).Error("failed saving execution payload in memcached") + } + }() + } + } + + nextTime = time.Now().UTC() + pf.RedisUpdate = uint64(nextTime.Sub(prevTime).Microseconds()) + pf.Total = uint64(nextTime.Sub(receivedAt).Microseconds()) + + // All done, log with profiling information + log.WithFields(logrus.Fields{ + "profileDecodeUs": pf.Decode, + "profilePrechecksUs": pf.Prechecks, + "profileSimUs": pf.Simulation, + "profileRedisUs": pf.RedisUpdate, + "profileTotalUs": pf.Total, + }).Info("received block from builder") + w.WriteHeader(http.StatusOK) +} + +func (api *RelayAPI) handleSubscribeConstraints(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "text/event-stream") + w.Header().Set("Cache-Control", "no-cache") + w.Header().Set("Connection", "keep-alive") + + // TODO: authenticate this call properly to avoid spamming/dos + + constraintsCh := make(chan *ConstraintSubmission) + api.constraintsConsumers = append(api.constraintsConsumers, constraintsCh) + + flusher, ok := w.(http.Flusher) + if !ok { + http.Error(w, "Streaming unsupported!", http.StatusInternalServerError) + return + } + + for constraint := range constraintsCh { + constraintJSON, err := constraint.MarshalJSON() + if err != nil { + api.log.WithError(err).Error("failed to marshal constraint to json") + continue + } + fmt.Fprint(w, string(constraintJSON)) + flusher.Flush() + } +} + // --------------- // // INTERNAL APIS diff --git a/mev-boost-relay/services/api/service_test.go b/mev-boost-relay/services/api/service_test.go index 4bcf7e97..be73cf1e 100644 --- a/mev-boost-relay/services/api/service_test.go +++ b/mev-boost-relay/services/api/service_test.go @@ -348,6 +348,9 @@ func TestSubmitConstraints(t *testing.T) { }) } +func TestSubscribeToConstraints(t *testing.T) { +} + func TestBuilderApiGetValidators(t *testing.T) { path := "/relay/v1/builder/validators" diff --git a/mev-boost-relay/services/api/utils.go b/mev-boost-relay/services/api/utils.go index 55948ee2..782f6bb5 100644 --- a/mev-boost-relay/services/api/utils.go +++ b/mev-boost-relay/services/api/utils.go @@ -150,3 +150,9 @@ func verifyBlockSignature(block *common.VersionedSignedBlindedBeaconBlock, domai func getPayloadAttributesKey(parentHash string, slot uint64) string { return fmt.Sprintf("%s-%d", parentHash, slot) } + +func broadcastToChannels[T any](constraintsConsumers []chan *T, constraint *T) { + for _, consumer := range constraintsConsumers { + consumer <- constraint + } +} From 3c4e054ef83b0174456d6ce1550fea8f813df181 Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Mon, 20 May 2024 11:29:56 +0200 Subject: [PATCH 05/15] asdf --- mev-boost-relay/services/api/service.go | 1 + mev-boost-relay/services/api/service_test.go | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/mev-boost-relay/services/api/service.go b/mev-boost-relay/services/api/service.go index 76417fa5..611a592c 100644 --- a/mev-boost-relay/services/api/service.go +++ b/mev-boost-relay/services/api/service.go @@ -368,6 +368,7 @@ func (api *RelayAPI) getRouter() http.Handler { r.HandleFunc(pathSubmitNewBlock, api.handleSubmitNewBlock).Methods(http.MethodPost) // BOLT r.HandleFunc(pathSubmitNewBlockWithPreconfs, api.handleSubmitNewBlockWithPreconfs).Methods(http.MethodPost) + r.HandleFunc(pathSubscribeConstraints, api.handleSubscribeConstraints).Methods(http.MethodPost) } // Data API diff --git a/mev-boost-relay/services/api/service_test.go b/mev-boost-relay/services/api/service_test.go index be73cf1e..9585b93d 100644 --- a/mev-boost-relay/services/api/service_test.go +++ b/mev-boost-relay/services/api/service_test.go @@ -348,7 +348,13 @@ func TestSubmitConstraints(t *testing.T) { }) } +// TODO: finish this func TestSubscribeToConstraints(t *testing.T) { + backend := newTestBackend(t, 1) + + path := "/relay/v1/builder/constraints/subscribe" + rr := backend.request(http.MethodPost, path, nil) + require.Equal(t, http.StatusOK, rr.Code) } func TestBuilderApiGetValidators(t *testing.T) { From 110396a96bd8369cb36653d81e1f6ca9a5e2f9ce Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Wed, 22 May 2024 16:22:22 +0200 Subject: [PATCH 06/15] fix: handleSubscribeConstraint test. - from POST to GET - forked flashbots' go-utils because 'responseWriter' doesn't implement Flusher interface, and the way wrapper structs and interfaces work in Golang is a nice gotcha --- mev-boost-relay/common/common.go | 2 +- mev-boost-relay/datastore/memcached.go | 2 +- mev-boost-relay/datastore/redis.go | 2 +- mev-boost-relay/go.mod | 4 ++-- mev-boost-relay/go.sum | 7 ++----- .../services/api/blocksim_ratelimiter.go | 4 ++-- mev-boost-relay/services/api/service.go | 13 +++++++------ mev-boost-relay/services/api/service_test.go | 13 ++++++++++--- mev-boost-relay/services/website/website.go | 2 +- 9 files changed, 27 insertions(+), 22 deletions(-) diff --git a/mev-boost-relay/common/common.go b/mev-boost-relay/common/common.go index 21bce2f1..bf27b617 100644 --- a/mev-boost-relay/common/common.go +++ b/mev-boost-relay/common/common.go @@ -6,7 +6,7 @@ import ( "fmt" "time" - "github.com/flashbots/go-utils/cli" + "github.com/thedevbirb/flashbots-go-utils/cli" ) var ( diff --git a/mev-boost-relay/datastore/memcached.go b/mev-boost-relay/datastore/memcached.go index a0ee56b2..b15ec2d8 100644 --- a/mev-boost-relay/datastore/memcached.go +++ b/mev-boost-relay/datastore/memcached.go @@ -7,7 +7,7 @@ import ( builderApi "github.com/attestantio/go-builder-client/api" "github.com/bradfitz/gomemcache/memcache" - "github.com/flashbots/go-utils/cli" + "github.com/thedevbirb/flashbots-go-utils/cli" ) var ( diff --git a/mev-boost-relay/datastore/redis.go b/mev-boost-relay/datastore/redis.go index b7dac1d3..0e5b6be9 100644 --- a/mev-boost-relay/datastore/redis.go +++ b/mev-boost-relay/datastore/redis.go @@ -15,7 +15,7 @@ import ( builderSpec "github.com/attestantio/go-builder-client/spec" "github.com/attestantio/go-eth2-client/spec" "github.com/attestantio/go-eth2-client/spec/capella" - "github.com/flashbots/go-utils/cli" + "github.com/thedevbirb/flashbots-go-utils/cli" "github.com/flashbots/mev-boost-relay/common" "github.com/go-redis/redis/v9" "github.com/sirupsen/logrus" diff --git a/mev-boost-relay/go.mod b/mev-boost-relay/go.mod index acadc7cf..8d6dfe02 100644 --- a/mev-boost-relay/go.mod +++ b/mev-boost-relay/go.mod @@ -12,7 +12,6 @@ require ( github.com/buger/jsonparser v1.1.1 github.com/ethereum/go-ethereum v1.13.15 github.com/flashbots/go-boost-utils v1.8.0 - github.com/flashbots/go-utils v0.5.0 github.com/go-redis/redis/v9 v9.0.0-rc.1 github.com/gorilla/mux v1.8.1 github.com/holiman/uint256 v1.2.4 @@ -24,6 +23,7 @@ require ( github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.8.4 github.com/tdewolff/minify v2.3.6+incompatible + github.com/thedevbirb/flashbots-go-utils v0.0.0-20240522133809-7f0a4449ea2a go.uber.org/atomic v1.11.0 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa golang.org/x/text v0.14.0 @@ -32,7 +32,6 @@ require ( require ( github.com/DataDog/zstd v1.5.2 // indirect github.com/StackExchange/wmi v1.2.1 // indirect - github.com/VictoriaMetrics/fastcache v1.12.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/cockroachdb/errors v1.9.1 // indirect @@ -46,6 +45,7 @@ require ( github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect github.com/fatih/color v1.16.0 // indirect + github.com/flashbots/go-utils v0.5.0 // indirect github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect github.com/go-gorp/gorp/v3 v3.1.0 // indirect diff --git a/mev-boost-relay/go.sum b/mev-boost-relay/go.sum index 48b583a7..d6fe17ec 100644 --- a/mev-boost-relay/go.sum +++ b/mev-boost-relay/go.sum @@ -20,8 +20,6 @@ github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZp github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/miniredis/v2 v2.31.0 h1:ObEFUNlJwoIiyjxdrYF0QIDE7qXcLc7D3WpSH4c22PU= github.com/alicebob/miniredis/v2 v2.31.0/go.mod h1:UB/T2Uztp7MlFSDakaX1sTXUv5CASoprx0wulRT6HBg= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/attestantio/go-builder-client v0.4.3-0.20240124194555-d44db06f45fa h1:Kj6d1tXAA+EAi7fK8z8NakBEpY4WYzZMuCmLZjwBpTM= github.com/attestantio/go-builder-client v0.4.3-0.20240124194555-d44db06f45fa/go.mod h1:e02i/WO4fjs3/u9oIZEjiC8CK1Qyxy4cpiMMGKx4VqQ= @@ -123,8 +121,6 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= -github.com/ethereum/go-ethereum v1.13.10 h1:Ppdil79nN+Vc+mXfge0AuUgmKWuVv4eMqzoIVSdqZek= -github.com/ethereum/go-ethereum v1.13.10/go.mod h1:sc48XYQxCzH3fG9BcrXCOOgQk2JfZzNAmIKnceogzsA= github.com/ethereum/go-ethereum v1.13.15 h1:U7sSGYGo4SPjP6iNIifNoyIAiNjrmQkz6EwQG+/EZWo= github.com/ethereum/go-ethereum v1.13.15/go.mod h1:TN8ZiHrdJwSe8Cb6x+p0hs5CxhJZPbqB7hHkaUXcmIU= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= @@ -156,7 +152,6 @@ github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3Bop github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs= github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= -github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= @@ -434,6 +429,8 @@ github.com/tdewolff/parse v2.3.4+incompatible h1:x05/cnGwIMf4ceLuDMBOdQ1qGniMoxp github.com/tdewolff/parse v2.3.4+incompatible/go.mod h1:8oBwCsVmUkgHO8M5iCzSIDtpzXOT0WXX9cWhz+bIzJQ= github.com/tdewolff/test v1.0.7 h1:8Vs0142DmPFW/bQeHRP3MV19m1gvndjUb1sn8yy74LM= github.com/tdewolff/test v1.0.7/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= +github.com/thedevbirb/flashbots-go-utils v0.0.0-20240522133809-7f0a4449ea2a h1:KluRm3uBBAp8c3c3mcIj6VOA55I8FyipixzhcMPuEcQ= +github.com/thedevbirb/flashbots-go-utils v0.0.0-20240522133809-7f0a4449ea2a/go.mod h1:Xcc4QMCD1U+HqHayd9nqVMcJVV4eAzNyAQVWY1AqhEE= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= diff --git a/mev-boost-relay/services/api/blocksim_ratelimiter.go b/mev-boost-relay/services/api/blocksim_ratelimiter.go index 9f2634db..715e5916 100644 --- a/mev-boost-relay/services/api/blocksim_ratelimiter.go +++ b/mev-boost-relay/services/api/blocksim_ratelimiter.go @@ -13,8 +13,8 @@ import ( "time" "github.com/attestantio/go-eth2-client/spec" - "github.com/flashbots/go-utils/cli" - "github.com/flashbots/go-utils/jsonrpc" + "github.com/thedevbirb/flashbots-go-utils/cli" + "github.com/thedevbirb/flashbots-go-utils/jsonrpc" "github.com/flashbots/mev-boost-relay/common" ) diff --git a/mev-boost-relay/services/api/service.go b/mev-boost-relay/services/api/service.go index 611a592c..9898bfa8 100644 --- a/mev-boost-relay/services/api/service.go +++ b/mev-boost-relay/services/api/service.go @@ -28,8 +28,6 @@ import ( "github.com/flashbots/go-boost-utils/bls" "github.com/flashbots/go-boost-utils/ssz" "github.com/flashbots/go-boost-utils/utils" - "github.com/flashbots/go-utils/cli" - "github.com/flashbots/go-utils/httplogger" "github.com/flashbots/mev-boost-relay/beaconclient" "github.com/flashbots/mev-boost-relay/common" "github.com/flashbots/mev-boost-relay/database" @@ -39,6 +37,8 @@ import ( "github.com/holiman/uint256" "github.com/pkg/errors" "github.com/sirupsen/logrus" + "github.com/thedevbirb/flashbots-go-utils/cli" + "github.com/thedevbirb/flashbots-go-utils/httplogger" uberatomic "go.uber.org/atomic" "golang.org/x/exp/slices" ) @@ -75,7 +75,7 @@ var ( // BOLT: allow builders to ship merkle proofs with their blocks pathSubmitNewBlockWithPreconfs = "/relay/v1/builder/blocks_with_preconfs" // BOLT: allow builders to subscribe to constraints - pathSubscribeConstraints = "/relay/v1/builder/constraints/subscribe" + pathSubscribeConstraints = "/relay/v1/builder/constraints" // Data API pathDataProposerPayloadDelivered = "/relay/v1/data/bidtraces/proposer_payload_delivered" @@ -296,7 +296,7 @@ func NewRelayAPI(opts RelayAPIOpts) (api *RelayAPI, err error) { memcached: opts.Memcached, db: opts.DB, constraints: NewConstraintCache(), - constraintsConsumers: make([]chan *ConstraintSubmission, 5), + constraintsConsumers: make([]chan *ConstraintSubmission, 0, 10), payloadAttributes: make(map[string]payloadAttributesHelper), @@ -368,7 +368,7 @@ func (api *RelayAPI) getRouter() http.Handler { r.HandleFunc(pathSubmitNewBlock, api.handleSubmitNewBlock).Methods(http.MethodPost) // BOLT r.HandleFunc(pathSubmitNewBlockWithPreconfs, api.handleSubmitNewBlockWithPreconfs).Methods(http.MethodPost) - r.HandleFunc(pathSubscribeConstraints, api.handleSubscribeConstraints).Methods(http.MethodPost) + r.HandleFunc(pathSubscribeConstraints, api.handleSubscribeConstraints).Methods(http.MethodGet) } // Data API @@ -1639,6 +1639,7 @@ func (api *RelayAPI) handleSubmitConstraints(w http.ResponseWriter, req *http.Re ua := req.UserAgent() headSlot := api.headSlot.Load() receivedAt := time.Now().UTC() + log := api.log.WithFields(logrus.Fields{ "method": "getPayload", "ua": ua, @@ -2801,7 +2802,7 @@ func (api *RelayAPI) handleSubscribeConstraints(w http.ResponseWriter, req *http // TODO: authenticate this call properly to avoid spamming/dos - constraintsCh := make(chan *ConstraintSubmission) + constraintsCh := make(chan *ConstraintSubmission, 1000) api.constraintsConsumers = append(api.constraintsConsumers, constraintsCh) flusher, ok := w.(http.Flusher) diff --git a/mev-boost-relay/services/api/service_test.go b/mev-boost-relay/services/api/service_test.go index 9585b93d..3d507bc7 100644 --- a/mev-boost-relay/services/api/service_test.go +++ b/mev-boost-relay/services/api/service_test.go @@ -352,9 +352,16 @@ func TestSubmitConstraints(t *testing.T) { func TestSubscribeToConstraints(t *testing.T) { backend := newTestBackend(t, 1) - path := "/relay/v1/builder/constraints/subscribe" - rr := backend.request(http.MethodPost, path, nil) - require.Equal(t, http.StatusOK, rr.Code) + path := "/relay/v1/builder/constraints" + go func() { + rr := backend.request(http.MethodGet, path, nil) + require.Equal(t, http.StatusOK, rr.Code) + }() + + // Wait 1 sec for the goroutine to start and add the consumer + time.Sleep(1 * time.Second) + + backend.relay.constraintsConsumers[0] <- &ConstraintSubmission{} } func TestBuilderApiGetValidators(t *testing.T) { diff --git a/mev-boost-relay/services/website/website.go b/mev-boost-relay/services/website/website.go index 5044ad12..81fb869e 100644 --- a/mev-boost-relay/services/website/website.go +++ b/mev-boost-relay/services/website/website.go @@ -14,7 +14,7 @@ import ( "github.com/NYTimes/gziphandler" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/flashbots/go-utils/httplogger" + "github.com/thedevbirb/flashbots-go-utils/httplogger" "github.com/flashbots/mev-boost-relay/common" "github.com/flashbots/mev-boost-relay/database" "github.com/flashbots/mev-boost-relay/datastore" From 2c2f7d91144cc60734594bee3d31e7b3e3c20a9c Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Wed, 22 May 2024 16:40:38 +0200 Subject: [PATCH 07/15] chore(constraints submission): logs + channel handling --- mev-boost-relay/services/api/service.go | 40 ++++++++++++++++---- mev-boost-relay/services/api/service_test.go | 3 ++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/mev-boost-relay/services/api/service.go b/mev-boost-relay/services/api/service.go index 9898bfa8..602c564d 100644 --- a/mev-boost-relay/services/api/service.go +++ b/mev-boost-relay/services/api/service.go @@ -592,6 +592,16 @@ func (api *RelayAPI) startValidatorRegistrationDBProcessor() { } } +// removeConstraintsConsumer is an helper function to remove the consumer from the list +func (api *RelayAPI) removeConstraintsConsumer(ch chan *ConstraintSubmission) { + for i, c := range api.constraintsConsumers { + if c == ch { + api.constraintsConsumers = append(api.constraintsConsumers[:i], api.constraintsConsumers[i+1:]...) + break + } + } +} + // simulateBlock sends a request for a block simulation to blockSimRateLimiter. func (api *RelayAPI) simulateBlock(ctx context.Context, opts blockSimOptions) (requestErr, validationErr error) { t := time.Now() @@ -2810,15 +2820,31 @@ func (api *RelayAPI) handleSubscribeConstraints(w http.ResponseWriter, req *http http.Error(w, "Streaming unsupported!", http.StatusInternalServerError) return } + // Remove the consumer and close the channel when the client disconnects + defer func() { + api.removeConstraintsConsumer(constraintsCh) + close(constraintsCh) + }() - for constraint := range constraintsCh { - constraintJSON, err := constraint.MarshalJSON() - if err != nil { - api.log.WithError(err).Error("failed to marshal constraint to json") - continue + // Monitor client disconnect + notify := req.Context().Done() + + for { + select { + case <-notify: + // Client disconnected + return + case constraint := <-constraintsCh: + constraintJSON, err := constraint.MarshalJSON() + api.log.Infof("New constraint received: %s", constraint) + + if err != nil { + api.log.Printf("failed to marshal constraint to json: %v", err) + continue + } + fmt.Fprint(w, string(constraintJSON)) + flusher.Flush() } - fmt.Fprint(w, string(constraintJSON)) - flusher.Flush() } } diff --git a/mev-boost-relay/services/api/service_test.go b/mev-boost-relay/services/api/service_test.go index 3d507bc7..a0ddb766 100644 --- a/mev-boost-relay/services/api/service_test.go +++ b/mev-boost-relay/services/api/service_test.go @@ -353,6 +353,9 @@ func TestSubscribeToConstraints(t *testing.T) { backend := newTestBackend(t, 1) path := "/relay/v1/builder/constraints" + + // Run the request in a goroutine so that it doesn't block the test, + // but it finishes as soon as the message is sent over the channel go func() { rr := backend.request(http.MethodGet, path, nil) require.Equal(t, http.StatusOK, rr.Code) From f20d8c58e42139e9d7b1567fa1403c0b729bf0c2 Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Thu, 23 May 2024 12:10:53 +0200 Subject: [PATCH 08/15] fix: flushing + gzip compression; test subscribe to constraint working --- mev-boost-relay/go.mod | 5 +- mev-boost-relay/go.sum | 6 +- mev-boost-relay/services/api/service.go | 34 +++++----- mev-boost-relay/services/api/service_test.go | 70 ++++++++++++++++++-- 4 files changed, 88 insertions(+), 27 deletions(-) diff --git a/mev-boost-relay/go.mod b/mev-boost-relay/go.mod index 8d6dfe02..9315c1f9 100644 --- a/mev-boost-relay/go.mod +++ b/mev-boost-relay/go.mod @@ -1,6 +1,6 @@ module github.com/flashbots/mev-boost-relay -go 1.21 +go 1.22.2 require ( github.com/NYTimes/gziphandler v1.1.1 @@ -23,7 +23,7 @@ require ( github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.8.4 github.com/tdewolff/minify v2.3.6+incompatible - github.com/thedevbirb/flashbots-go-utils v0.0.0-20240522133809-7f0a4449ea2a + github.com/thedevbirb/flashbots-go-utils v0.0.0-20240522160613-f4f36d8f39af go.uber.org/atomic v1.11.0 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa golang.org/x/text v0.14.0 @@ -45,7 +45,6 @@ require ( github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect github.com/fatih/color v1.16.0 // indirect - github.com/flashbots/go-utils v0.5.0 // indirect github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect github.com/go-gorp/gorp/v3 v3.1.0 // indirect diff --git a/mev-boost-relay/go.sum b/mev-boost-relay/go.sum index d6fe17ec..9bc80580 100644 --- a/mev-boost-relay/go.sum +++ b/mev-boost-relay/go.sum @@ -131,8 +131,6 @@ github.com/ferranbt/fastssz v0.1.3 h1:ZI+z3JH05h4kgmFXdHuR1aWYsgrg7o+Fw7/NCzM16M github.com/ferranbt/fastssz v0.1.3/go.mod h1:0Y9TEd/9XuFlh7mskMPfXiI2Dkw4Ddg9EyXt1W7MRvE= github.com/flashbots/go-boost-utils v1.8.0 h1:z3K1hw+Fbl9AGMNQKnK7Bvf0M/rKgjfruAEvra+Z8Mg= github.com/flashbots/go-boost-utils v1.8.0/go.mod h1:Ry1Rw8Lx5v1rpAR0+IvR4sV10jYAeQaGVM3vRD8mYdM= -github.com/flashbots/go-utils v0.5.0 h1:ldjWta9B9//DJU2QcwRbErez3+1aKhSn6EoFc6d5kPY= -github.com/flashbots/go-utils v0.5.0/go.mod h1:LauDwifaRdSK0mS5X34GR59pJtUu1T/lOFNdff1BqtI= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -429,8 +427,8 @@ github.com/tdewolff/parse v2.3.4+incompatible h1:x05/cnGwIMf4ceLuDMBOdQ1qGniMoxp github.com/tdewolff/parse v2.3.4+incompatible/go.mod h1:8oBwCsVmUkgHO8M5iCzSIDtpzXOT0WXX9cWhz+bIzJQ= github.com/tdewolff/test v1.0.7 h1:8Vs0142DmPFW/bQeHRP3MV19m1gvndjUb1sn8yy74LM= github.com/tdewolff/test v1.0.7/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= -github.com/thedevbirb/flashbots-go-utils v0.0.0-20240522133809-7f0a4449ea2a h1:KluRm3uBBAp8c3c3mcIj6VOA55I8FyipixzhcMPuEcQ= -github.com/thedevbirb/flashbots-go-utils v0.0.0-20240522133809-7f0a4449ea2a/go.mod h1:Xcc4QMCD1U+HqHayd9nqVMcJVV4eAzNyAQVWY1AqhEE= +github.com/thedevbirb/flashbots-go-utils v0.0.0-20240522160613-f4f36d8f39af h1:VwsEpQJqCFCT+oZXfJj8alj3FkIpKLvn0wV7GO/cEQY= +github.com/thedevbirb/flashbots-go-utils v0.0.0-20240522160613-f4f36d8f39af/go.mod h1:Xcc4QMCD1U+HqHayd9nqVMcJVV4eAzNyAQVWY1AqhEE= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= diff --git a/mev-boost-relay/services/api/service.go b/mev-boost-relay/services/api/service.go index 602c564d..a3384b80 100644 --- a/mev-boost-relay/services/api/service.go +++ b/mev-boost-relay/services/api/service.go @@ -185,10 +185,6 @@ type RelayAPI struct { srvStarted uberatomic.Bool srvShutdown uberatomic.Bool - constraintsSse *http.Server - constraintsSseStarted uberatomic.Bool - constraintsSseShutdown uberatomic.Bool - beaconClient beaconclient.IMultiBeaconClient datastore *datastore.Datastore redis *datastore.RedisCache @@ -516,11 +512,6 @@ func (api *RelayAPI) StartServer() (err error) { return nil } - err = api.constraintsSse.ListenAndServe() - if errors.Is(err, http.ErrServerClosed) { - return nil - } - return err } @@ -2809,23 +2800,30 @@ func (api *RelayAPI) handleSubscribeConstraints(w http.ResponseWriter, req *http w.Header().Set("Content-Type", "text/event-stream") w.Header().Set("Cache-Control", "no-cache") w.Header().Set("Connection", "keep-alive") + // NOTE: Apparently, we need gzip for SSE flushing to work properly + w.Header().Set("Content-Encoding", "gzip") // TODO: authenticate this call properly to avoid spamming/dos + // Add the new consumer constraintsCh := make(chan *ConstraintSubmission, 1000) api.constraintsConsumers = append(api.constraintsConsumers, constraintsCh) - flusher, ok := w.(http.Flusher) - if !ok { - http.Error(w, "Streaming unsupported!", http.StatusInternalServerError) - return - } // Remove the consumer and close the channel when the client disconnects defer func() { api.removeConstraintsConsumer(constraintsCh) close(constraintsCh) }() + gzipWriter := gzip.NewWriter(w) + defer gzipWriter.Close() + + flusher, ok := w.(http.Flusher) + if !ok { + http.Error(w, "Streaming unsupported!", http.StatusInternalServerError) + return + } + // Monitor client disconnect notify := req.Context().Done() @@ -2842,7 +2840,13 @@ func (api *RelayAPI) handleSubscribeConstraints(w http.ResponseWriter, req *http api.log.Printf("failed to marshal constraint to json: %v", err) continue } - fmt.Fprint(w, string(constraintJSON)) + fmt.Fprintf(gzipWriter, "data: %s\n\n", string(constraintJSON)) + + // NOTE: Flushing the gzip.Writer ensures that any compressed data in the buffer is + // written out to the underlying http.ResponseWriter. The http.ResponseWriter + // itself may also buffer data. Calling Flush on the http.ResponseWriter ensures + // that any data buffered by the HTTP server is sent to the client immediately. + gzipWriter.Flush() flusher.Flush() } } diff --git a/mev-boost-relay/services/api/service_test.go b/mev-boost-relay/services/api/service_test.go index a0ddb766..b0a646e7 100644 --- a/mev-boost-relay/services/api/service_test.go +++ b/mev-boost-relay/services/api/service_test.go @@ -1,14 +1,19 @@ package api import ( + "bufio" "bytes" "compress/gzip" "context" "encoding/json" + "errors" "fmt" + "io" + "log" "math/big" "net/http" "net/http/httptest" + "strings" "testing" "time" @@ -348,23 +353,78 @@ func TestSubmitConstraints(t *testing.T) { }) } -// TODO: finish this func TestSubscribeToConstraints(t *testing.T) { backend := newTestBackend(t, 1) - path := "/relay/v1/builder/constraints" + // Create and start HTTP server. + // This will server the endpoint to subscribe to constraints via SSE + go func() { + backend.relay.srv = &http.Server{ + Addr: backend.relay.opts.ListenAddr, + Handler: backend.relay.getRouter(), + + ReadTimeout: time.Duration(apiReadTimeoutMs) * time.Millisecond, + ReadHeaderTimeout: time.Duration(apiReadHeaderTimeoutMs) * time.Millisecond, + WriteTimeout: time.Duration(apiWriteTimeoutMs) * time.Millisecond, + IdleTimeout: time.Duration(apiIdleTimeoutMs) * time.Millisecond, + MaxHeaderBytes: apiMaxHeaderBytes, + } + + t.Logf("Server starting on %s", backend.relay.opts.ListenAddr) + err := backend.relay.srv.ListenAndServe() + if errors.Is(err, http.ErrServerClosed) { + t.Log("Server closed") + return + } + }() + + // Wait for the server to start + time.Sleep(500 * time.Millisecond) + // Run the request in a goroutine so that it doesn't block the test, // but it finishes as soon as the message is sent over the channel go func() { - rr := backend.request(http.MethodGet, path, nil) - require.Equal(t, http.StatusOK, rr.Code) + url := "http://" + backend.relay.opts.ListenAddr + path + // NOTE: this response arrives after the first data is flushed + resp, err := http.Get(url) + if err != nil { + log.Fatalf("Failed to connect to SSE server: %v", err) + } + if resp.StatusCode != http.StatusOK { + log.Fatalf("Non-OK HTTP status: %s", resp.Status) + } + defer resp.Body.Close() + + bufReader := bufio.NewReader(resp.Body) + for { + line, err := bufReader.ReadString('\n') + if err != nil { + if err == io.EOF { + fmt.Println("End of stream") + break + } + log.Fatalf("Error reading from response body: %v", err) + } + + if strings.HasPrefix(line, "data: ") { + data := strings.TrimPrefix(line, "data: ") + fmt.Printf("Received event: %s\n", data) + } + } }() - // Wait 1 sec for the goroutine to start and add the consumer + // Wait for the HTTP request goroutine to start and add the consumer time.Sleep(1 * time.Second) + // Now we can safely send the constraints, and we should get a response + // in the HTTP request defined in the goroutine above backend.relay.constraintsConsumers[0] <- &ConstraintSubmission{} + time.Sleep(500 * time.Millisecond) + backend.relay.constraintsConsumers[0] <- &ConstraintSubmission{} + + // Wait for the HTTP request goroutine to process the constraints + time.Sleep(2 * time.Second) } func TestBuilderApiGetValidators(t *testing.T) { From 4b16b4c498d1e53f8ce34dbb34f898b66788c861 Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Thu, 23 May 2024 15:30:51 +0200 Subject: [PATCH 09/15] feat: constraint subscription authorization --- mev-boost-relay/go.mod | 2 + mev-boost-relay/services/api/service.go | 21 +++++++-- mev-boost-relay/services/api/service_test.go | 31 ++++++++++--- mev-boost-relay/services/api/types.go | 16 +++++++ mev-boost-relay/services/api/utils.go | 47 ++++++++++++++++++++ 5 files changed, 108 insertions(+), 9 deletions(-) diff --git a/mev-boost-relay/go.mod b/mev-boost-relay/go.mod index 9315c1f9..abc21cf5 100644 --- a/mev-boost-relay/go.mod +++ b/mev-boost-relay/go.mod @@ -27,6 +27,7 @@ require ( go.uber.org/atomic v1.11.0 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa golang.org/x/text v0.14.0 + gotest.tools v2.2.0+incompatible ) require ( @@ -54,6 +55,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/google/uuid v1.3.1 // indirect github.com/klauspost/compress v1.15.15 // indirect github.com/kr/pretty v0.3.1 // indirect diff --git a/mev-boost-relay/services/api/service.go b/mev-boost-relay/services/api/service.go index a3384b80..3e74fcfc 100644 --- a/mev-boost-relay/services/api/service.go +++ b/mev-boost-relay/services/api/service.go @@ -2800,13 +2800,28 @@ func (api *RelayAPI) handleSubscribeConstraints(w http.ResponseWriter, req *http w.Header().Set("Content-Type", "text/event-stream") w.Header().Set("Cache-Control", "no-cache") w.Header().Set("Connection", "keep-alive") - // NOTE: Apparently, we need gzip for SSE flushing to work properly + // NOTE: This http.ResponseWriter uses gzip and we need this otherwise we're not able + // to flush data properly w.Header().Set("Content-Encoding", "gzip") - // TODO: authenticate this call properly to avoid spamming/dos + // TODO: Docs regarding this autorization schema + // NOTE: This authorization schema is not final, but works for now. + auth := req.Header.Get("Authorization") + + builderPublicKey, err := validateConstraintSubscriptionAuth(auth, api.headSlot.Load()) + if err != nil { + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + + _, ok := api.checkBuilderEntry(w, api.log, builderPublicKey) + if !ok { + http.Error(w, "Builder rejected", http.StatusUnauthorized) + return + } // Add the new consumer - constraintsCh := make(chan *ConstraintSubmission, 1000) + constraintsCh := make(chan *ConstraintSubmission) api.constraintsConsumers = append(api.constraintsConsumers, constraintsCh) // Remove the consumer and close the channel when the client disconnects diff --git a/mev-boost-relay/services/api/service_test.go b/mev-boost-relay/services/api/service_test.go index b0a646e7..98df344a 100644 --- a/mev-boost-relay/services/api/service_test.go +++ b/mev-boost-relay/services/api/service_test.go @@ -36,6 +36,7 @@ import ( "github.com/holiman/uint256" "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" + "gotest.tools/assert" ) const ( @@ -382,18 +383,36 @@ func TestSubscribeToConstraints(t *testing.T) { // Wait for the server to start time.Sleep(500 * time.Millisecond) + // Setup information of the builder making the request + builderPrivateKey, builderPublicKey, err := bls.GenerateNewKeypair() + require.NoError(t, err) + var phase0BuilderPublicKey phase0.BLSPubKey = builderPublicKey.Bytes() + + headSlot := backend.relay.headSlot.Load() + message, err := json.Marshal(ConstraintSubscriptionAuth{PublicKey: phase0BuilderPublicKey, Slot: headSlot}) + require.NoError(t, err) + signatureEC := bls.Sign(builderPrivateKey, message) + subscriptionSignatureJSON := `"` + phase0.BLSSignature(bls.SignatureToBytes(signatureEC)[:]).String() + `"` + // Run the request in a goroutine so that it doesn't block the test, // but it finishes as soon as the message is sent over the channel go func() { url := "http://" + backend.relay.opts.ListenAddr + path - // NOTE: this response arrives after the first data is flushed - resp, err := http.Get(url) + req, err := http.NewRequest(http.MethodGet, url, nil) if err != nil { - log.Fatalf("Failed to connect to SSE server: %v", err) - } - if resp.StatusCode != http.StatusOK { - log.Fatalf("Non-OK HTTP status: %s", resp.Status) + log.Fatalf("Failed to create request: %v", err) } + + // Add authentication + authHeader := "BOLT " + subscriptionSignatureJSON + "," + string(message) + req.Header.Set("Authorization", authHeader) + + // Send the request + client := &http.Client{} + // NOTE: this response arrives after the first data is flushed + resp, err := client.Do(req) + assert.Equal(t, err, nil) + assert.Equal(t, resp.StatusCode, http.StatusOK) defer resp.Body.Close() bufReader := bufio.NewReader(resp.Body) diff --git a/mev-boost-relay/services/api/types.go b/mev-boost-relay/services/api/types.go index 9e5f9652..8b1972a4 100644 --- a/mev-boost-relay/services/api/types.go +++ b/mev-boost-relay/services/api/types.go @@ -1,8 +1,11 @@ package api import ( + "encoding/json" "errors" + "fmt" + "github.com/attestantio/go-eth2-client/spec/phase0" boostTypes "github.com/flashbots/go-boost-utils/types" ) @@ -23,3 +26,16 @@ type HTTPErrorResp struct { type HTTPMessageResp struct { Message string `json:"message"` } + +type ConstraintSubscriptionAuth struct { + PublicKey phase0.BLSPubKey `json:"publicKey"` + Slot uint64 `json:"slot"` +} + +func (c *ConstraintSubscriptionAuth) String() string { + buf, err := json.Marshal(c) + if err != nil { + return fmt.Sprintf("failed to marshal ConstraintSubscriptionAuth: %v", err) + } + return string(buf) +} diff --git a/mev-boost-relay/services/api/utils.go b/mev-boost-relay/services/api/utils.go index 782f6bb5..91787cfb 100644 --- a/mev-boost-relay/services/api/utils.go +++ b/mev-boost-relay/services/api/utils.go @@ -1,7 +1,9 @@ package api import ( + "encoding/json" "fmt" + "strings" builderApi "github.com/attestantio/go-builder-client/api" "github.com/attestantio/go-eth2-client/spec" @@ -156,3 +158,48 @@ func broadcastToChannels[T any](constraintsConsumers []chan *T, constraint *T) { consumer <- constraint } } + +// validateConstraintSubscriptionAuth checks the authentication string data from the Builder, +// and returns its BLS public key if the authentication is valid. +func validateConstraintSubscriptionAuth(auth string, headSlot uint64) (phase0.BLSPubKey, error) { + zeroKey := phase0.BLSPubKey{} + if auth == "" { + return zeroKey, errors.Errorf("Authorization header missing") + } + // Authorization: + parts := strings.Split(auth, " ") + if len(parts) != 2 { + return zeroKey, errors.Errorf("Ill-formed authorization header") + } + if parts[0] != "BOLT" { + return zeroKey, errors.Errorf("Not BOLT authentication scheme") + } + // , + parts = strings.SplitN(parts[1], ",", 2) + if len(parts) != 2 { + return zeroKey, errors.Errorf("Ill-formed authorization header") + } + + signature := new(phase0.BLSSignature) + if err := signature.UnmarshalJSON([]byte(parts[0])); err != nil { + fmt.Println("Failed to unmarshal authData: ", err) + return zeroKey, errors.Errorf("Ill-formed authorization header") + } + + authDataRaw := []byte(parts[1]) + authData := new(ConstraintSubscriptionAuth) + if err := json.Unmarshal(authDataRaw, authData); err != nil { + fmt.Println("Failed to unmarshal authData: ", err) + return zeroKey, errors.Errorf("Ill-formed authorization header") + } + + if headSlot != authData.Slot { + return zeroKey, errors.Errorf("Invalid head slot") + } + + ok, err := bls.VerifySignatureBytes(authDataRaw, signature[:], authData.PublicKey[:]) + if err != nil || !ok { + return zeroKey, errors.Errorf("Invalid signature") + } + return authData.PublicKey, nil +} From c8a715f2fad86c1e5f4f79f5c09df3793b2ac80c Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Thu, 23 May 2024 15:51:36 +0200 Subject: [PATCH 10/15] chore(relay): cleanup --- mev-boost-relay/services/api/constraints.go | 1 + mev-boost-relay/services/api/service.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mev-boost-relay/services/api/constraints.go b/mev-boost-relay/services/api/constraints.go index 810d12a3..5194fca2 100644 --- a/mev-boost-relay/services/api/constraints.go +++ b/mev-boost-relay/services/api/constraints.go @@ -1,3 +1,4 @@ +// This code is taken from https://github.com/chainbound/bolt/pull/11/files#diff-0fa8405accc1cdc5b108ba0210a8f1d99e25e1a5173e45e1516d73c294b061c4 package api import ( diff --git a/mev-boost-relay/services/api/service.go b/mev-boost-relay/services/api/service.go index 3e74fcfc..a0fd3066 100644 --- a/mev-boost-relay/services/api/service.go +++ b/mev-boost-relay/services/api/service.go @@ -2404,7 +2404,7 @@ func (api *RelayAPI) handleSubmitNewBlock(w http.ResponseWriter, req *http.Reque w.WriteHeader(http.StatusOK) } -// TODO(bolt): We should check the preconfirmation proofs in this function to discard bids that are not valid. +// TODO: We should check the preconfirmation proofs in this function to discard bids that are not valid. // This is necessary to avoid the relay accept a high bid with invalid proofs, resulting in a missed opportunity // for the proposer, who will refuse to sign the associated block header. func (api *RelayAPI) handleSubmitNewBlockWithPreconfs(w http.ResponseWriter, req *http.Request) { From 4dfebcdf02080adbfebfd4ab434dd8e86337fdd6 Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Thu, 23 May 2024 16:12:15 +0200 Subject: [PATCH 11/15] chore(relay): test submitconstraints uses channels --- mev-boost-relay/services/api/service.go | 3 ++- mev-boost-relay/services/api/service_test.go | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/mev-boost-relay/services/api/service.go b/mev-boost-relay/services/api/service.go index a0fd3066..c99ad1b7 100644 --- a/mev-boost-relay/services/api/service.go +++ b/mev-boost-relay/services/api/service.go @@ -1748,6 +1748,7 @@ func (api *RelayAPI) handleSubmitConstraints(w http.ResponseWriter, req *http.Re }).Info("[BOLT]: adding inclusion constraint to cache") broadcastToChannels(api.constraintsConsumers, constraint) + fmt.Println("after broadcast to channels") // Add the constraint to the cache. They will be cleared when we receive a payload for the slot // in `handleGetPayload` @@ -2821,7 +2822,7 @@ func (api *RelayAPI) handleSubscribeConstraints(w http.ResponseWriter, req *http } // Add the new consumer - constraintsCh := make(chan *ConstraintSubmission) + constraintsCh := make(chan *ConstraintSubmission, 256) api.constraintsConsumers = append(api.constraintsConsumers, constraintsCh) // Remove the consumer and close the channel when the client disconnects diff --git a/mev-boost-relay/services/api/service_test.go b/mev-boost-relay/services/api/service_test.go index 98df344a..f8089d6e 100644 --- a/mev-boost-relay/services/api/service_test.go +++ b/mev-boost-relay/services/api/service_test.go @@ -338,14 +338,18 @@ func TestSubmitConstraints(t *testing.T) { payload := []*SignedConstraintSubmission{&signedConstraintSubmission} t.Run("Constraints sent", func(t *testing.T) { + ch := make(chan *ConstraintSubmission, 256) + backend.relay.constraintsConsumers = []chan *ConstraintSubmission{ch} rr := backend.request(http.MethodPost, path, payload) require.Equal(t, http.StatusOK, rr.Code) constraintCache := backend.relay.constraints expected := constraintCache.Get(slot)[txHash] actual := Constraint{RawTx: constraintSubmission.RawTx} + actualFromCh := <-backend.relay.constraintsConsumers[0] + actualConstraintFromCh := Constraint{RawTx: actualFromCh.RawTx} - require.Equal(t, expected, &actual) + require.Equal(t, expected, &actual, actualConstraintFromCh) }) t.Run("Empty constraint list", func(t *testing.T) { From ce5dd229c8dcf97b461d93eeca2faafb78a2496b Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Thu, 23 May 2024 16:37:09 +0200 Subject: [PATCH 12/15] chore(relay): replace constraint cache hashmap with fifomap --- mev-boost-relay/go.mod | 1 + mev-boost-relay/go.sum | 2 ++ mev-boost-relay/services/api/service.go | 21 ++++++++++++-------- mev-boost-relay/services/api/service_test.go | 4 +++- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/mev-boost-relay/go.mod b/mev-boost-relay/go.mod index abc21cf5..8370a5f0 100644 --- a/mev-boost-relay/go.mod +++ b/mev-boost-relay/go.mod @@ -19,6 +19,7 @@ require ( github.com/lib/pq v1.10.8 github.com/pkg/errors v0.9.1 github.com/r3labs/sse/v2 v2.10.0 + github.com/chainbound/shardmap v0.0.2 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.0 github.com/stretchr/testify v1.8.4 diff --git a/mev-boost-relay/go.sum b/mev-boost-relay/go.sum index 9bc80580..f61dcb9b 100644 --- a/mev-boost-relay/go.sum +++ b/mev-boost-relay/go.sum @@ -63,6 +63,8 @@ github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx2 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chainbound/shardmap v0.0.2 h1:yB1weccdm2vC6dnqzzLwPIvyAnRj7815mJWbkPybiYw= +github.com/chainbound/shardmap v0.0.2/go.mod h1:TBvIzhHyFUbt+oa3UzbijobTUh221st6xIbuki7WzPc= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= diff --git a/mev-boost-relay/services/api/service.go b/mev-boost-relay/services/api/service.go index c99ad1b7..06f9e567 100644 --- a/mev-boost-relay/services/api/service.go +++ b/mev-boost-relay/services/api/service.go @@ -25,6 +25,7 @@ import ( "github.com/attestantio/go-eth2-client/spec" "github.com/attestantio/go-eth2-client/spec/phase0" "github.com/buger/jsonparser" + "github.com/chainbound/shardmap" "github.com/flashbots/go-boost-utils/bls" "github.com/flashbots/go-boost-utils/ssz" "github.com/flashbots/go-boost-utils/utils" @@ -190,7 +191,7 @@ type RelayAPI struct { redis *datastore.RedisCache memcached *datastore.Memcached db database.IDatabaseService - constraints *ConstraintCache + constraints *shardmap.FIFOMap[uint64, *Constraints] constraintsConsumers []chan *ConstraintSubmission headSlot uberatomic.Uint64 @@ -291,7 +292,7 @@ func NewRelayAPI(opts RelayAPIOpts) (api *RelayAPI, err error) { redis: opts.Redis, memcached: opts.Memcached, db: opts.DB, - constraints: NewConstraintCache(), + constraints: shardmap.NewFIFOMap[uint64, *Constraints](64, 8, shardmap.HashUint64), // 2 epochs cache constraintsConsumers: make([]chan *ConstraintSubmission, 0, 10), payloadAttributes: make(map[string]payloadAttributesHelper), @@ -1748,12 +1749,16 @@ func (api *RelayAPI) handleSubmitConstraints(w http.ResponseWriter, req *http.Re }).Info("[BOLT]: adding inclusion constraint to cache") broadcastToChannels(api.constraintsConsumers, constraint) - fmt.Println("after broadcast to channels") - // Add the constraint to the cache. They will be cleared when we receive a payload for the slot - // in `handleGetPayload` - // TODO: actually do that. Alternative could be use a timer + go routine instead of modifying the getPayload call - api.constraints.AddInclusionConstraint(constraint.Slot, constraint.TxHash, constraint.RawTx) + // Add the constraint to the cache. + slotConstraints, _ := api.constraints.Get(constraint.Slot) + if slotConstraints == nil { + constraints := make(Constraints) + constraints[constraint.TxHash] = &Constraint{RawTx: constraint.RawTx} + api.constraints.Put(constraint.Slot, &constraints) + } else { + (*slotConstraints)[constraint.TxHash] = &Constraint{RawTx: constraint.RawTx} + } } // respond to the HTTP request @@ -2474,7 +2479,7 @@ func (api *RelayAPI) handleSubmitNewBlockWithPreconfs(w http.ResponseWriter, req // Check for SSZ encoding contentType := req.Header.Get("Content-Type") if contentType == "application/octet-stream" { - // TODO-BOLT: implement SSZ decoding + // TODO: (BOLT) implement SSZ decoding panic("SSZ decoding not implemented for preconfs yet") } else { log = log.WithField("reqContentType", "json") diff --git a/mev-boost-relay/services/api/service_test.go b/mev-boost-relay/services/api/service_test.go index f8089d6e..e93007ca 100644 --- a/mev-boost-relay/services/api/service_test.go +++ b/mev-boost-relay/services/api/service_test.go @@ -344,7 +344,9 @@ func TestSubmitConstraints(t *testing.T) { require.Equal(t, http.StatusOK, rr.Code) constraintCache := backend.relay.constraints - expected := constraintCache.Get(slot)[txHash] + slotConstraints, _ := constraintCache.Get(slot) + require.NotNil(t, slotConstraints) + expected := (*slotConstraints)[txHash] actual := Constraint{RawTx: constraintSubmission.RawTx} actualFromCh := <-backend.relay.constraintsConsumers[0] actualConstraintFromCh := Constraint{RawTx: actualFromCh.RawTx} From 9065e03ab6dfa7727862c0b503fc534b47b36d1e Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Wed, 29 May 2024 12:42:18 +0200 Subject: [PATCH 13/15] chore: after rebase cleanup --- mev-boost-relay/services/api/preconf.go | 425 ------------------------ mev-boost-relay/services/api/service.go | 14 + 2 files changed, 14 insertions(+), 425 deletions(-) delete mode 100644 mev-boost-relay/services/api/preconf.go diff --git a/mev-boost-relay/services/api/preconf.go b/mev-boost-relay/services/api/preconf.go deleted file mode 100644 index aafecab9..00000000 --- a/mev-boost-relay/services/api/preconf.go +++ /dev/null @@ -1,425 +0,0 @@ -package api - -import ( - "compress/gzip" - "context" - "encoding/json" - "fmt" - "io" - "net/http" - "os" - "strings" - "time" - - "github.com/flashbots/go-boost-utils/ssz" - "github.com/flashbots/mev-boost-relay/common" - "github.com/sirupsen/logrus" -) - -// TODO(bolt): We should check the preconfirmation proofs in this function to discard bids that are not valid. -// This is necessary to avoid the relay accept a high bid with invalid proofs, resulting in a missed opportunity -// for the proposer, who will refuse to sign the associated block header. -// -// For the POC this is not needed -func (api *RelayAPI) handleSubmitNewBlockWithPreconfs(w http.ResponseWriter, req *http.Request) { - var pf common.Profile - var prevTime, nextTime time.Time - - headSlot := api.headSlot.Load() - receivedAt := time.Now().UTC() - prevTime = receivedAt - - args := req.URL.Query() - isCancellationEnabled := args.Get("cancellations") == "1" - - log := api.log.WithFields(logrus.Fields{ - "method": "submitNewBlockWithPreconfs", - "contentLength": req.ContentLength, - "headSlot": headSlot, - "cancellationEnabled": isCancellationEnabled, - "timestampRequestStart": receivedAt.UnixMilli(), - }) - - // Log at start and end of request - log.Info("request initiated") - defer func() { - log.WithFields(logrus.Fields{ - "timestampRequestFin": time.Now().UTC().UnixMilli(), - "requestDurationMs": time.Since(receivedAt).Milliseconds(), - }).Info("request finished") - }() - - // If cancellations are disabled but builder requested it, return error - if isCancellationEnabled && !api.ffEnableCancellations { - log.Info("builder submitted with cancellations enabled, but feature flag is disabled") - api.RespondError(w, http.StatusBadRequest, "cancellations are disabled") - return - } - - var err error - var reader io.Reader = req.Body - isGzip := req.Header.Get("Content-Encoding") == "gzip" - log = log.WithField("reqIsGzip", isGzip) - if isGzip { - reader, err = gzip.NewReader(req.Body) - if err != nil { - log.WithError(err).Warn("could not create gzip reader") - api.RespondError(w, http.StatusBadRequest, err.Error()) - return - } - } - - limitReader := io.LimitReader(reader, 10*1024*1024) // 10 MB - requestPayloadBytes, err := io.ReadAll(limitReader) - if err != nil { - log.WithError(err).Warn("could not read payload") - api.RespondError(w, http.StatusBadRequest, err.Error()) - return - } - - nextTime = time.Now().UTC() - pf.PayloadLoad = uint64(nextTime.Sub(prevTime).Microseconds()) - prevTime = nextTime - - // BOLT: new payload type - payload := new(common.VersionedSubmitBlockRequestWithPreconfsProofs) - - // Check for SSZ encoding - contentType := req.Header.Get("Content-Type") - if contentType == "application/octet-stream" { - // TODO-BOLT: implement SSZ decoding - panic("SSZ decoding not implemented for preconfs yet") - } else { - log = log.WithField("reqContentType", "json") - if err := json.Unmarshal(requestPayloadBytes, payload); err != nil { - api.boltLog.WithError(err).Warn("Could not decode payload - JSON") - api.RespondError(w, http.StatusBadRequest, err.Error()) - return - } - } - - // BOLT: Send an event to the web demo - if len(payload.Proofs) > 0 { - slot, _ := payload.Inner.Slot() - message := fmt.Sprintf("BOLT-RELAY: received block bid with %d preconfirmations for slot %d", len(payload.Proofs), slot) - event := strings.NewReader(fmt.Sprintf("{ \"message\": \"%s\"}", message)) - eventRes, err := http.Post("http://host.docker.internal:3001/events", "application/json", event) - if err != nil { - log.Error("Failed to log preconfirms event: ", err) - } - if eventRes != nil { - defer eventRes.Body.Close() - } - } - - num, _ := payload.Inner.BlockNumber() - bhash, _ := payload.Inner.BlockHash() - api.boltLog.Infof("Got decoded payload from builder: \nPayload: %v\nBlock hash: %s\nBlockNum: %d\n", payload.Inner.String(), bhash, num) - api.boltLog.Infof("Headslot: %d\n", headSlot) - - nextTime = time.Now().UTC() - pf.Decode = uint64(nextTime.Sub(prevTime).Microseconds()) - prevTime = nextTime - - isLargeRequest := len(requestPayloadBytes) > fastTrackPayloadSizeLimit - // getting block submission info also validates bid trace and execution submission are not empty - submission, err := common.GetBlockSubmissionInfo(payload.Inner) - if err != nil { - log.WithError(err).Warn("missing fields in submit block request") - api.RespondError(w, http.StatusBadRequest, err.Error()) - return - } - log = log.WithFields(logrus.Fields{ - "timestampAfterDecoding": time.Now().UTC().UnixMilli(), - "slot": submission.BidTrace.Slot, - "builderPubkey": submission.BidTrace.BuilderPubkey.String(), - "blockHash": submission.BidTrace.BlockHash.String(), - "proposerPubkey": submission.BidTrace.ProposerPubkey.String(), - "parentHash": submission.BidTrace.ParentHash.String(), - "value": submission.BidTrace.Value.Dec(), - "numTx": len(submission.Transactions), - "payloadBytes": len(requestPayloadBytes), - "isLargeRequest": isLargeRequest, - }) - // deneb specific logging - if payload.Inner.Deneb != nil { - log = log.WithFields(logrus.Fields{ - "numBlobs": len(payload.Inner.Deneb.BlobsBundle.Blobs), - "blobGasUsed": payload.Inner.Deneb.ExecutionPayload.BlobGasUsed, - "excessBlobGas": payload.Inner.Deneb.ExecutionPayload.ExcessBlobGas, - }) - } - - ok := api.checkSubmissionSlotDetails(w, log, headSlot, payload.Inner, submission) - if !ok { - return - } - - builderPubkey := submission.BidTrace.BuilderPubkey - builderEntry, ok := api.checkBuilderEntry(w, log, builderPubkey) - if !ok { - return - } - - log = log.WithField("builderIsHighPrio", builderEntry.status.IsHighPrio) - - gasLimit, ok := api.checkSubmissionFeeRecipient(w, log, submission.BidTrace) - if !ok { - return - } - - // Don't accept blocks with 0 value - if submission.BidTrace.Value.ToBig().Cmp(ZeroU256.BigInt()) == 0 || len(submission.Transactions) == 0 { - log.Info("submitNewBlock failed: block with 0 value or no txs") - w.WriteHeader(http.StatusOK) - return - } - - // Sanity check the submission - err = SanityCheckBuilderBlockSubmission(payload.Inner) - if err != nil { - log.WithError(err).Info("block submission sanity checks failed") - api.RespondError(w, http.StatusBadRequest, err.Error()) - return - } - - attrs, ok := api.checkSubmissionPayloadAttrs(w, log, submission) - if !ok { - return - } - - // Verify the signature - log = log.WithField("timestampBeforeSignatureCheck", time.Now().UTC().UnixMilli()) - signature := submission.Signature - ok, err = ssz.VerifySignature(submission.BidTrace, api.opts.EthNetDetails.DomainBuilder, builderPubkey[:], signature[:]) - log = log.WithField("timestampAfterSignatureCheck", time.Now().UTC().UnixMilli()) - if err != nil { - log.WithError(err).Warn("failed verifying builder signature") - api.RespondError(w, http.StatusBadRequest, "failed verifying builder signature") - return - } else if !ok { - log.Warn("invalid builder signature") - api.RespondError(w, http.StatusBadRequest, "invalid signature") - return - } - - log = log.WithField("timestampBeforeCheckingFloorBid", time.Now().UTC().UnixMilli()) - - // Create the redis pipeline tx - tx := api.redis.NewTxPipeline() - - // channel to send simulation result to the deferred function - simResultC := make(chan *blockSimResult, 1) - var eligibleAt time.Time // will be set once the bid is ready - - submission, err = common.GetBlockSubmissionInfo(payload.Inner) - if err != nil { - log.WithError(err).Warn("missing fields in submit block request") - api.RespondError(w, http.StatusBadRequest, err.Error()) - return - } - - bfOpts := bidFloorOpts{ - w: w, - tx: tx, - log: log, - cancellationsEnabled: isCancellationEnabled, - simResultC: simResultC, - submission: submission, - } - floorBidValue, ok := api.checkFloorBidValue(bfOpts) - if !ok { - return - } - - log = log.WithField("timestampAfterCheckingFloorBid", time.Now().UTC().UnixMilli()) - - // Deferred saving of the builder submission to database (whenever this function ends) - defer func() { - savePayloadToDatabase := !api.ffDisablePayloadDBStorage - var simResult *blockSimResult - select { - case simResult = <-simResultC: - case <-time.After(10 * time.Second): - log.Warn("timed out waiting for simulation result") - simResult = &blockSimResult{false, false, nil, nil} - } - - submissionEntry, err := api.db.SaveBuilderBlockSubmission( - payload.Inner, - simResult.requestErr, - simResult.validationErr, - receivedAt, - eligibleAt, - simResult.wasSimulated, - savePayloadToDatabase, - pf, - simResult.optimisticSubmission, - payload.Proofs, // BOLT: add merkle proofs to the submission - ) - if err != nil { - log.WithError(err).WithField("payload", payload).Error("saving builder block submission to database failed") - return - } - - err = api.db.UpsertBlockBuilderEntryAfterSubmission(submissionEntry, simResult.validationErr != nil) - if err != nil { - log.WithError(err).Error("failed to upsert block-builder-entry") - } - }() - - // --------------------------------- - // THE BID WILL BE SIMULATED SHORTLY - // --------------------------------- - - log = log.WithField("timestampBeforeCheckingTopBid", time.Now().UTC().UnixMilli()) - - // Get the latest top bid value from Redis - bidIsTopBid := false - topBidValue, err := api.redis.GetTopBidValue(context.Background(), tx, submission.BidTrace.Slot, submission.BidTrace.ParentHash.String(), submission.BidTrace.ProposerPubkey.String()) - if err != nil { - log.WithError(err).Error("failed to get top bid value from redis") - } else { - bidIsTopBid = submission.BidTrace.Value.ToBig().Cmp(topBidValue) == 1 - log = log.WithFields(logrus.Fields{ - "topBidValue": topBidValue.String(), - "newBidIsTopBid": bidIsTopBid, - }) - } - - log = log.WithField("timestampAfterCheckingTopBid", time.Now().UTC().UnixMilli()) - - nextTime = time.Now().UTC() - pf.Prechecks = uint64(nextTime.Sub(prevTime).Microseconds()) - prevTime = nextTime - - // Simulate the block submission and save to db - fastTrackValidation := builderEntry.status.IsHighPrio && bidIsTopBid && !isLargeRequest - timeBeforeValidation := time.Now().UTC() - - log = log.WithFields(logrus.Fields{ - "timestampBeforeValidation": timeBeforeValidation.UTC().UnixMilli(), - "fastTrackValidation": fastTrackValidation, - }) - - // Construct simulation request - opts := blockSimOptions{ - isHighPrio: builderEntry.status.IsHighPrio, - fastTrack: fastTrackValidation, - log: log, - builder: builderEntry, - req: &common.BuilderBlockValidationRequest{ - VersionedSubmitBlockRequest: payload.Inner, - RegisteredGasLimit: gasLimit, - ParentBeaconBlockRoot: attrs.parentBeaconRoot, - }, - } - // With sufficient collateral, process the block optimistically. - if builderEntry.status.IsOptimistic && - builderEntry.collateral.Cmp(submission.BidTrace.Value.ToBig()) >= 0 && - submission.BidTrace.Slot == api.optimisticSlot.Load() { - go api.processOptimisticBlock(opts, simResultC) - } else { - // Simulate block (synchronously). - requestErr, validationErr := api.simulateBlock(context.Background(), opts) // success/error logging happens inside - simResultC <- &blockSimResult{requestErr == nil, false, requestErr, validationErr} - validationDurationMs := time.Since(timeBeforeValidation).Milliseconds() - log = log.WithFields(logrus.Fields{ - "timestampAfterValidation": time.Now().UTC().UnixMilli(), - "validationDurationMs": validationDurationMs, - }) - if requestErr != nil { // Request error - if os.IsTimeout(requestErr) { - api.RespondError(w, http.StatusGatewayTimeout, "validation request timeout") - } else { - api.RespondError(w, http.StatusBadRequest, requestErr.Error()) - } - return - } else { - if validationErr != nil { - api.RespondError(w, http.StatusBadRequest, validationErr.Error()) - return - } - } - } - - nextTime = time.Now().UTC() - pf.Simulation = uint64(nextTime.Sub(prevTime).Microseconds()) - prevTime = nextTime - - // If cancellations are enabled, then abort now if this submission is not the latest one - if isCancellationEnabled { - // Ensure this request is still the latest one. This logic intentionally ignores the value of the bids and makes the current active bid the one - // that arrived at the relay last. This allows for builders to reduce the value of their bid (effectively cancel a high bid) by ensuring a lower - // bid arrives later. Even if the higher bid takes longer to simulate, by checking the receivedAt timestamp, this logic ensures that the low bid - // is not overwritten by the high bid. - // - // NOTE: this can lead to a rather tricky race condition. If a builder submits two blocks to the relay concurrently, then the randomness of network - // latency will make it impossible to predict which arrives first. Thus a high bid could unintentionally be overwritten by a low bid that happened - // to arrive a few microseconds later. If builders are submitting blocks at a frequency where they cannot reliably predict which bid will arrive at - // the relay first, they should instead use multiple pubkeys to avoid uninitentionally overwriting their own bids. - latestPayloadReceivedAt, err := api.redis.GetBuilderLatestPayloadReceivedAt(context.Background(), tx, submission.BidTrace.Slot, submission.BidTrace.BuilderPubkey.String(), submission.BidTrace.ParentHash.String(), submission.BidTrace.ProposerPubkey.String()) - if err != nil { - log.WithError(err).Error("failed getting latest payload receivedAt from redis") - } else if receivedAt.UnixMilli() < latestPayloadReceivedAt { - log.Infof("already have a newer payload: now=%d / prev=%d", receivedAt.UnixMilli(), latestPayloadReceivedAt) - api.RespondError(w, http.StatusBadRequest, "already using a newer payload") - return - } - } - redisOpts := redisUpdateBidOpts{ - w: w, - tx: tx, - log: log, - cancellationsEnabled: isCancellationEnabled, - receivedAt: receivedAt, - floorBidValue: floorBidValue, - payload: payload.Inner, - } - updateBidResult, getPayloadResponse, ok := api.updateRedisBid(redisOpts, payload.Proofs) - if !ok { - return - } - - // Add fields to logs - log = log.WithFields(logrus.Fields{ - "timestampAfterBidUpdate": time.Now().UTC().UnixMilli(), - "wasBidSavedInRedis": updateBidResult.WasBidSaved, - "wasTopBidUpdated": updateBidResult.WasTopBidUpdated, - "topBidValue": updateBidResult.TopBidValue, - "prevTopBidValue": updateBidResult.PrevTopBidValue, - "profileRedisSavePayloadUs": updateBidResult.TimeSavePayload.Microseconds(), - "profileRedisUpdateTopBidUs": updateBidResult.TimeUpdateTopBid.Microseconds(), - "profileRedisUpdateFloorUs": updateBidResult.TimeUpdateFloor.Microseconds(), - }) - - if updateBidResult.WasBidSaved { - // Bid is eligible to win the auction - eligibleAt = time.Now().UTC() - log = log.WithField("timestampEligibleAt", eligibleAt.UnixMilli()) - - // Save to memcache in the background - if api.memcached != nil { - go func() { - err = api.memcached.SaveExecutionPayload(submission.BidTrace.Slot, submission.BidTrace.ProposerPubkey.String(), submission.BidTrace.BlockHash.String(), getPayloadResponse) - if err != nil { - log.WithError(err).Error("failed saving execution payload in memcached") - } - }() - } - } - - nextTime = time.Now().UTC() - pf.RedisUpdate = uint64(nextTime.Sub(prevTime).Microseconds()) - pf.Total = uint64(nextTime.Sub(receivedAt).Microseconds()) - - // All done, log with profiling information - log.WithFields(logrus.Fields{ - "profileDecodeUs": pf.Decode, - "profilePrechecksUs": pf.Prechecks, - "profileSimUs": pf.Simulation, - "profileRedisUs": pf.RedisUpdate, - "profileTotalUs": pf.Total, - }).Info("received block from builder") - w.WriteHeader(http.StatusOK) -} diff --git a/mev-boost-relay/services/api/service.go b/mev-boost-relay/services/api/service.go index 06f9e567..b4527b9b 100644 --- a/mev-boost-relay/services/api/service.go +++ b/mev-boost-relay/services/api/service.go @@ -2490,6 +2490,20 @@ func (api *RelayAPI) handleSubmitNewBlockWithPreconfs(w http.ResponseWriter, req } } + // BOLT: Send an event to the web demo + if len(payload.Proofs) > 0 { + slot, _ := payload.Inner.Slot() + message := fmt.Sprintf("BOLT-RELAY: received block bid with %d preconfirmations for slot %d", len(payload.Proofs), slot) + event := strings.NewReader(fmt.Sprintf("{ \"message\": \"%s\"}", message)) + eventRes, err := http.Post("http://host.docker.internal:3001/events", "application/json", event) + if err != nil { + log.Error("Failed to log preconfirms event: ", err) + } + if eventRes != nil { + defer eventRes.Body.Close() + } + } + num, _ := payload.Inner.BlockNumber() bhash, _ := payload.Inner.BlockHash() api.boltLog.Infof("Got decoded payload from builder: \nPayload: %v\nBlock hash: %s\nBlockNum: %d\n", payload.Inner.String(), bhash, num) From 9c2fd72da43936c9806b2d2fdbc21599dfb464ae Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Fri, 24 May 2024 09:35:28 +0200 Subject: [PATCH 14/15] feat(relay): add proof verification on handle submit block, wip --- mev-boost-relay/common/preconf.go | 76 +++-- mev-boost-relay/services/api/constraints.go | 3 +- mev-boost-relay/services/api/proofs.go | 85 +++++ mev-boost-relay/services/api/service.go | 15 + mev-boost-relay/services/api/service_test.go | 160 ++++++++++ ...mitBlockPayloadWithProofsDeneb_Goerli.json | 294 ++++++++++++++++++ 6 files changed, 599 insertions(+), 34 deletions(-) create mode 100644 mev-boost-relay/services/api/proofs.go create mode 100644 mev-boost-relay/testdata/submitBlockPayloadWithProofsDeneb_Goerli.json diff --git a/mev-boost-relay/common/preconf.go b/mev-boost-relay/common/preconf.go index 164026d0..fa274d29 100644 --- a/mev-boost-relay/common/preconf.go +++ b/mev-boost-relay/common/preconf.go @@ -9,12 +9,51 @@ import ( "strings" fastSsz "github.com/ferranbt/fastssz" + "github.com/sirupsen/logrus" builderSpec "github.com/attestantio/go-builder-client/spec" "github.com/attestantio/go-eth2-client/spec/phase0" - "github.com/sirupsen/logrus" ) +// VersionedSubmitBlockRequestWithPreconfsProofs is a wrapper struct +// over `builderSpec.VersionedSubmitBlockRequest` +// to include preconfirmation proofs +type VersionedSubmitBlockRequestWithPreconfsProofs struct { + Inner *VersionedSubmitBlockRequest `json:"inner"` + Proofs []*PreconfirmationWithProof `json:"proofs"` +} + +func (v *VersionedSubmitBlockRequestWithPreconfsProofs) String() string { + out, err := json.Marshal(v) + if err != nil { + return err.Error() + } + return string(out) +} + +type BidWithPreconfirmationsProofs struct { + // The block bid + Bid *builderSpec.VersionedSignedBuilderBid `json:"bid"` + // The preconfirmations with proofs + Proofs []*PreconfirmationWithProof `json:"proofs"` +} + +func (b *BidWithPreconfirmationsProofs) String() string { + out, err := json.Marshal(b) + if err != nil { + return err.Error() + } + return string(out) +} + +func (p *PreconfirmationWithProof) String() string { + proofs, err := json.Marshal(p) + if err != nil { + return err.Error() + } + return string(proofs) +} + type HexBytes []byte // MarshalJSON implements json.Marshaler. @@ -65,9 +104,11 @@ func (s *SerializedMerkleProof) FromFastSszProof(p *fastSsz.Proof) { } } -func (s *SerializedMerkleProof) ToFastSszProof() *fastSsz.Proof { +// ToFastSszProof converts a SerializedMerkleProof to a fastssz.Proof. +func (s *SerializedMerkleProof) ToFastSszProof(leaf []byte) *fastSsz.Proof { p := &fastSsz.Proof{ Index: s.Index, + Leaf: leaf, Hashes: make([][]byte, len(s.Hashes)), } for i, h := range s.Hashes { @@ -85,37 +126,6 @@ type PreconfirmationWithProof struct { MerkleProof *SerializedMerkleProof `json:"merkleProof"` } -func (p PreconfirmationWithProof) String() string { - out, err := json.Marshal(p) - if err != nil { - return err.Error() - } - return string(out) -} - -// VersionedSubmitBlockRequestWithPreconfsProofs is a wrapper struct -// over `builderSpec.VersionedSubmitBlockRequest` -// to include preconfirmation proofs -type VersionedSubmitBlockRequestWithPreconfsProofs struct { - Inner *VersionedSubmitBlockRequest `json:"inner"` - Proofs []*PreconfirmationWithProof `json:"proofs"` -} - -func (v *VersionedSubmitBlockRequestWithPreconfsProofs) String() string { - out, err := json.Marshal(v) - if err != nil { - return err.Error() - } - return string(out) -} - -type BidWithPreconfirmationsProofs struct { - // The block bid - Bid *builderSpec.VersionedSignedBuilderBid `json:"bid"` - // The preconfirmations with proofs - Proofs []*PreconfirmationWithProof `json:"proofs"` -} - func NewBoltLogger(service string) *logrus.Entry { return LogSetup(false, "info").WithFields(logrus.Fields{ "service": fmt.Sprintf("BOLT-%s", service), diff --git a/mev-boost-relay/services/api/constraints.go b/mev-boost-relay/services/api/constraints.go index 5194fca2..5a0e0732 100644 --- a/mev-boost-relay/services/api/constraints.go +++ b/mev-boost-relay/services/api/constraints.go @@ -1,4 +1,3 @@ -// This code is taken from https://github.com/chainbound/bolt/pull/11/files#diff-0fa8405accc1cdc5b108ba0210a8f1d99e25e1a5173e45e1516d73c294b061c4 package api import ( @@ -11,6 +10,8 @@ import ( "github.com/pkg/errors" ) +// These types are taken from https://github.com/chainbound/bolt/pull/11/files#diff-0fa8405accc1cdc5b108ba0210a8f1d99e25e1a5173e45e1516d73c294b061c4 + type SignedConstraintSubmission struct { Message *ConstraintSubmission Signature phase0.BLSSignature `ssz-size:"96"` diff --git a/mev-boost-relay/services/api/proofs.go b/mev-boost-relay/services/api/proofs.go new file mode 100644 index 00000000..769ea4fe --- /dev/null +++ b/mev-boost-relay/services/api/proofs.go @@ -0,0 +1,85 @@ +package api + +import ( + "errors" + "fmt" + "time" + + "github.com/attestantio/go-eth2-client/spec/phase0" + fastSsz "github.com/ferranbt/fastssz" + "github.com/flashbots/mev-boost-relay/common" + "github.com/sirupsen/logrus" +) + +var ( + ErrNilProof = errors.New("nil proof") + ErrInvalidProofs = errors.New("proof verification failed") + ErrInvalidRoot = errors.New("failed getting tx root from bid") +) + +// verifyConstraintProofs verifies the proofs against the constraints, and returns an error if the proofs are invalid. +func (api *RelayAPI) verifyConstraintProofs(transactionsRoot phase0.Root, proofs []*common.PreconfirmationWithProof, constraints Constraints) error { + log := api.log.WithFields(logrus.Fields{}) + // BOLT: verify preconfirmation inclusion proofs. If they don't match, we don't consider the bid to be valid. + if proofs != nil { + // BOLT: remove unnecessary fields while logging + log.WithFields(logrus.Fields{}) + + log.WithField("len", len(proofs)).Info("[BOLT]: Verifying constraint proofs") + + for _, proof := range proofs { + if proof == nil { + log.Warn("[BOLT]: Nil proof!") + return ErrNilProof + } + + // Find the raw tx with the hash specified + constraint, ok := constraints[proof.TxHash] + if !ok { + log.Warnf("[BOLT]: Tx hash %s not found in constraints", proof.TxHash.String()) + // We don't actually have to return an error here, the relay just provided a proof that was unnecessary + continue + } + + rawTx := constraint.RawTx + + log.Infof("[BOLT]: Raw tx: %x", rawTx) + + if len(rawTx) == 0 { + log.Warnf("[BOLT]: Raw tx is empty for tx hash %s", proof.TxHash.String()) + continue + } + + // Compute the hash tree root for the raw preconfirmed transaction + // and use it as "Leaf" in the proof to be verified against + txHashTreeRoot, err := rawTx.HashTreeRoot() + if err != nil { + log.WithError(err).Error("[BOLT]: error getting tx hash tree root") + return ErrInvalidRoot + } + + log.Infof("[BOLT]: Tx hash tree root: %x", txHashTreeRoot) + + // Verify the proof + sszProof := proof.MerkleProof.ToFastSszProof(txHashTreeRoot[:]) + + currentTime := time.Now() + ok, err = fastSsz.VerifyProof(transactionsRoot[:], sszProof) + elapsed := time.Since(currentTime) + + if err != nil { + log.WithError(err).Error("error verifying merkle proof") + return err + } + + if !ok { + log.Error("[BOLT]: proof verification failed: 'not ok' for tx hash: ", proof.TxHash.String()) + return ErrInvalidProofs + } else { + log.Info(fmt.Sprintf("[BOLT]: Preconfirmation proof verified for tx hash %s in %s", proof.TxHash.String(), elapsed)) + } + } + } + + return nil +} diff --git a/mev-boost-relay/services/api/service.go b/mev-boost-relay/services/api/service.go index b4527b9b..040baa87 100644 --- a/mev-boost-relay/services/api/service.go +++ b/mev-boost-relay/services/api/service.go @@ -1980,6 +1980,21 @@ func (api *RelayAPI) updateRedisBid( return nil, nil, false } + // TODO: verify proofs here + slotConstraints, _ := api.constraints.Get(api.headSlot.Load()) + if slotConstraints != nil { + transactionsRoot, err := getHeaderResponse.TransactionsRoot() + if err != nil { + api.RespondError(opts.w, http.StatusBadRequest, err.Error()) + return nil, nil, false + } + err = api.verifyConstraintProofs(transactionsRoot, proofs, *slotConstraints) + if err != nil { + api.RespondError(opts.w, http.StatusBadRequest, err.Error()) + return nil, nil, false + } + } + getPayloadResponse, err := common.BuildGetPayloadResponse(opts.payload) if err != nil { opts.log.WithError(err).Error("could not build getPayload response") diff --git a/mev-boost-relay/services/api/service_test.go b/mev-boost-relay/services/api/service_test.go index e93007ca..b01b55e2 100644 --- a/mev-boost-relay/services/api/service_test.go +++ b/mev-boost-relay/services/api/service_test.go @@ -705,6 +705,166 @@ func TestBuilderSubmitBlock(t *testing.T) { } } +func TestBuilderSubmitBlockWithProofs(t *testing.T) { + type testHelper struct { + headSlot uint64 + submissionTimestamp int + parentHash string + feeRecipient string + withdrawalRoot string + prevRandao string + jsonReqSize int + sszReqSize int + jsonGzipReqSize int + sszGzipReqSize int + } + + testCases := []struct { + name string + filepath string + data testHelper + }{ + { + name: "Capella", + filepath: "../../testdata/submitBlockPayloadCapella_Goerli.json.gz", + data: testHelper{ + headSlot: 32, + submissionTimestamp: 1606824419, + parentHash: "0xbd3291854dc822b7ec585925cda0e18f06af28fa2886e15f52d52dd4b6f94ed6", + feeRecipient: "0x5cc0dde14e7256340cc820415a6022a7d1c93a35", + withdrawalRoot: "0xb15ed76298ff84a586b1d875df08b6676c98dfe9c7cd73fab88450348d8e70c8", + prevRandao: "0x9962816e9d0a39fd4c80935338a741dc916d1545694e41eb5a505e1a3098f9e4", + jsonReqSize: 704810, + sszReqSize: 352239, + jsonGzipReqSize: 207788, + sszGzipReqSize: 195923, + }, + }, + { + name: "Deneb", + filepath: "../../testdata/submitBlockPayloadDeneb_Goerli.json.gz", + data: testHelper{ + headSlot: 86, + submissionTimestamp: 1606825067, + parentHash: "0xb1bd772f909db1b6cbad8cf31745d3f2d692294998161369a5709c17a71f630f", + feeRecipient: "0x455E5AA18469bC6ccEF49594645666C587A3a71B", + withdrawalRoot: "0x3cb816ccf6bb079b4f462e81db1262064f321a4afa4ff32c1f7e0a1c603836af", + prevRandao: "0x6d414d3ffba7ba51155c3528739102c2889005940913b5d4c8031eed30764d4d", + jsonReqSize: 1744002, + sszReqSize: 872081, + jsonGzipReqSize: 385043, + sszGzipReqSize: 363271, + }, + }, + } + path := "/relay/v1/builder/blocks_with_preconfs" + backend := newTestBackend(t, 1) + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + headSlot := testCase.data.headSlot + submissionSlot := headSlot + 1 + submissionTimestamp := testCase.data.submissionTimestamp + + // Payload attributes + payloadJSONFilename := testCase.filepath + parentHash := testCase.data.parentHash + feeRec, err := utils.HexToAddress(testCase.data.feeRecipient) + require.NoError(t, err) + withdrawalsRoot, err := utils.HexToHash(testCase.data.withdrawalRoot) + require.NoError(t, err) + prevRandao := testCase.data.prevRandao + + // Setup the test relay backend + backend.relay.headSlot.Store(headSlot) + backend.relay.capellaEpoch = 0 + backend.relay.denebEpoch = 2 + backend.relay.proposerDutiesMap = make(map[uint64]*common.BuilderGetValidatorsResponseEntry) + backend.relay.proposerDutiesMap[headSlot+1] = &common.BuilderGetValidatorsResponseEntry{ + Slot: headSlot, + Entry: &builderApiV1.SignedValidatorRegistration{ + Message: &builderApiV1.ValidatorRegistration{ + FeeRecipient: feeRec, + }, + }, + } + backend.relay.payloadAttributes = make(map[string]payloadAttributesHelper) + backend.relay.payloadAttributes[parentHash] = payloadAttributesHelper{ + slot: submissionSlot, + parentHash: parentHash, + payloadAttributes: beaconclient.PayloadAttributes{ + PrevRandao: prevRandao, + }, + withdrawalsRoot: phase0.Root(withdrawalsRoot), + } + + // Prepare the request payload + req := new(common.VersionedSubmitBlockRequest) + requestPayloadJSONBytes := common.LoadGzippedBytes(t, payloadJSONFilename) + require.NoError(t, err) + err = json.Unmarshal(requestPayloadJSONBytes, req) + fmt.Println("json", string(requestPayloadJSONBytes)) + t.Fail() + require.NoError(t, err) + + // Update + switch req.Version { //nolint:exhaustive + case spec.DataVersionCapella: + req.Capella.Message.Slot = submissionSlot + req.Capella.ExecutionPayload.Timestamp = uint64(submissionTimestamp) + case spec.DataVersionDeneb: + req.Deneb.Message.Slot = submissionSlot + req.Deneb.ExecutionPayload.Timestamp = uint64(submissionTimestamp) + default: + require.Fail(t, "unknown data version") + } + + // Send JSON encoded request + reqJSONBytes, err := json.Marshal(req) + require.NoError(t, err) + require.Len(t, reqJSONBytes, testCase.data.jsonReqSize) + reqJSONBytes2, err := json.Marshal(req) + require.NoError(t, err) + require.Equal(t, reqJSONBytes, reqJSONBytes2) + rr := backend.requestBytes(http.MethodPost, path, reqJSONBytes, nil) + require.Contains(t, rr.Body.String(), "invalid signature") + require.Equal(t, http.StatusBadRequest, rr.Code) + + // Send SSZ encoded request + reqSSZBytes, err := req.MarshalSSZ() + require.NoError(t, err) + require.Len(t, reqSSZBytes, testCase.data.sszReqSize) + rr = backend.requestBytes(http.MethodPost, path, reqSSZBytes, map[string]string{ + "Content-Type": "application/octet-stream", + }) + require.Contains(t, rr.Body.String(), "invalid signature") + require.Equal(t, http.StatusBadRequest, rr.Code) + + // Send JSON+GZIP encoded request + headers := map[string]string{ + "Content-Encoding": "gzip", + } + jsonGzip := gzipBytes(t, reqJSONBytes) + require.Len(t, jsonGzip, testCase.data.jsonGzipReqSize) + rr = backend.requestBytes(http.MethodPost, path, jsonGzip, headers) + require.Contains(t, rr.Body.String(), "invalid signature") + require.Equal(t, http.StatusBadRequest, rr.Code) + + // Send SSZ+GZIP encoded request + headers = map[string]string{ + "Content-Type": "application/octet-stream", + "Content-Encoding": "gzip", + } + + sszGzip := gzipBytes(t, reqSSZBytes) + require.Len(t, sszGzip, testCase.data.sszGzipReqSize) + rr = backend.requestBytes(http.MethodPost, path, sszGzip, headers) + require.Contains(t, rr.Body.String(), "invalid signature") + require.Equal(t, http.StatusBadRequest, rr.Code) + }) + } +} + func TestCheckSubmissionFeeRecipient(t *testing.T) { cases := []struct { description string diff --git a/mev-boost-relay/testdata/submitBlockPayloadWithProofsDeneb_Goerli.json b/mev-boost-relay/testdata/submitBlockPayloadWithProofsDeneb_Goerli.json new file mode 100644 index 00000000..f275f171 --- /dev/null +++ b/mev-boost-relay/testdata/submitBlockPayloadWithProofsDeneb_Goerli.json @@ -0,0 +1,294 @@ +{ + "inner": { + "message": { + "slot": "5552306", + "parent_hash": "0xbd3291854dc822b7ec585925cda0e18f06af28fa2886e15f52d52dd4b6f94ed6", + "block_hash": "0x1bafdc454116b605005364976b134d761dd736cb4788d25c835783b46daeb121", + "builder_pubkey": "0xb67a5148a03229926e34b190af81a82a81c4df66831c98c03a139778418dd09a3b542ced0022620d19f35781ece6dc36", + "proposer_pubkey": "0x8559727ee65c295279332198029c939557f4d2aba0751fc55f71d0733b8aa17cd0301232a7f21a895f81eacf55c97ec4", + "proposer_fee_recipient": "0x5cC0DdE14E7256340CC820415a6022a7d1c93A35", + "gas_limit": "30000000", + "gas_used": "25875661", + "value": "71177763439091815" + }, + "execution_payload": { + "parent_hash": "0xbd3291854dc822b7ec585925cda0e18f06af28fa2886e15f52d52dd4b6f94ed6", + "fee_recipient": "0xb64a30399f7F6b0C154c2E7Af0a3ec7B0A5b131a", + "state_root": "0x74f74d15dcb00ba194901136f2019dd6be2d4c88c822786df90561a550193899", + "receipts_root": "0xb410fa34a1312626db3c41d325545e9f24e903d5dd9b9c260882aadb4c28fa8e", + "logs_bloom": "0x40f7484521e2f4f8001ed9b0810595c450380844af610944218104d21c220028aa6a150a86312b000040401909e548e71c6a05128a58607200103fc400346f6e9843c2e20c72a00d7bd8138a249a83208697c0d03d7633c18248a58fe88284240a0e43e782c6b0c1167a00ac9808be499950e8500228776980266490f21c9040b30a30b4922c3a7af850ba08f2000146ea850401e978038e1205094215025016ae8811166961477d68522c826c9a0d20228c822de2ac830503b13936b5e01b9f9532ec2322c70c491c1a21618533c284299b189207cf0e37f2c7a1930c6667815fd238290926265cc28095a0a0240234af3810928a962ad0264a4905018a02a1", + "prev_randao": "0x9962816e9d0a39fd4c80935338a741dc916d1545694e41eb5a505e1a3098f9e4", + "block_number": "8935900", + "gas_limit": "30000000", + "gas_used": "25875661", + "timestamp": "1683135672", + "extra_data": "0x496c6c756d696e61746520446d6f63726174697a6520447374726962757465", + "base_fee_per_gas": "19075240703", + "block_hash": "0x1bafdc454116b605005364976b134d761dd736cb4788d25c835783b46daeb121", + "transactions": [ + "0xf86f8304155e8535fad650928252089499e4530a9965dcaca8aad011714ce1446667e4eb88016345785d8a0000802ea0bef03fc632456d3b0f1506694c073c0c607a22eb6ac964538058b832c82d0cb2a02c525f632774f9990152b01d02e933008a23638cc0e4c569cf3853152e4a82c9", + "0xf86e8201bd852e90edd000830186a094d29c68d31ab1c10ce900479686fe3525669f17fe87038d7ea4c68000802da0ff22f8bfd0357a045c71757da6776fe2b38bf0d9ec9a4312389e2bb8c74e7f85a0734dc43fdafaf9ce06a013f024ea089c3bf9244679bfb798a4dd625bb77bb4db", + "0x02f8b105118520d1bfab5f852a4a4c643782e4409407865c6e87b9f70255377e024ace6630c1eaa37f80b844a9059cbb00000000000000000000000027bb53e4f40f0b44db0efb23cd9d88ef6d7b15a700000000000000000000000000000000000000000000000000000000000f4240c080a03ebb4568488336818788967183440aed83f2fc3b1f21281e9caf35830987d877a02f2e727f0e24167cc564fa3ca605ae4288039441938653e0afc1d0e8f1e7e553", + "0x02f8b20581e485174876e800854586f1ac5982b67a9402cdc279823190daf56860239e5f2680a50e3d0e80b844095ea7b3000000000000000000000000affa66384d9741a6eab6d426002721784d753fac00000000000000000000000000000000000000000000000001112af15d4635c3c001a008cd6e27cfb8401465c5cf7931416ddf24fbb84be60507d287a7efb1aec98220a063c88928e3794eedcc3902bdd6ff83e99316c34c77843facd4ef03e0d8678ad7", + "0xf9024e8309c31a8513b5fc2520831180e094a658742d33ebd2ce2f0bdff73515aa797fd161d980b901e4252f7b01000000000000000000000000000000000000000000000000000000000000006e0000000000000000000000004f7a67464b5976d7547c860109e4432d50afb38e0000000000000000000000000000000000000000000000000000000000030d40863f9169c3463fd8ec29548c1bba1acd37b550f53c48736f6e9b6d9f68c01f38863f9169c3463fd8ec29548c1bba1acd37b550f53c48736f6e9b6d9f68c01f3800000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000f40000000000000000000000004d73adb72bc3dd368966edd0f0b2148401a178e200000000000796ef006edd69db25f6d620a7bad3023c5d32761d353d3de9009a4f7a67464b5976d7547c860109e4432d50afb38e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000003bc991e9ee6a75f0000000000000000000000000000000000000000000000000000000000000014ee37567502d838e991dddc667f39bbfe0fc00afe0000000000000000000000000000000000000000000000002da0354b553325f76f371511523d3c07145b565af927bb0760f0e5cb45f4425a079ea035a2315e3360045723738eba65fb4163da66583a7e12e62dc1a7814f70b2b669", + "0xf86e83026e4b850deae7ffd182f61894bcd18f337f5a0cc819205004ff8bd05df282794c87470de4df820000802ea0c85c68ec90f6384cf92bd3523f66797e6b588a68013a269f646859f66c19a121a020611a2cba73bf6eb4a461496d7dc054f40f35aa758cdb9398926db9feb83ee4", + "0xf86e8304bdf0850deae7ffd182f618940739e9816ef6bad34fb9251706030c1c896ebd7287470de4df820000802ea0c4af6cd7e903f5b4982213585fc2e7fee46dec5a2f3d5051bce90f999c4935efa06eeb0d85ac2339eed6059468d043db89ca1f52ba66e83a845432bc76f509b5db", + "0xf86e83026e7a850deae7ffd182f61894f66266e6da69b2d5b454bddfc4fd03ec8474ac7087470de4df820000802ea053a312403d355028e1dfb8ef09bfc8321ec50d6ccc5cf8f0d41c5ad96f2d7363a03a7880ab997550b00e17fe4323f944255fd83b749be0cd28ccfd852a06076a73", + "0xf9024e8309c31b850b8b378a86831180e094a658742d33ebd2ce2f0bdff73515aa797fd161d980b901e4252f7b01000000000000000000000000000000000000000000000000000000000000006e0000000000000000000000004f7a67464b5976d7547c860109e4432d50afb38e0000000000000000000000000000000000000000000000000000000000030d4099453f564709b2da67bcc92f88376fa86e7a75b4a3bda1832383d2f2d9cbf17499453f564709b2da67bcc92f88376fa86e7a75b4a3bda1832383d2f2d9cbf17400000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000f40000000000000000000000004d73adb72bc3dd368966edd0f0b2148401a178e200000000000796f0006edd69db25f6d620a7bad3023c5d32761d353d3de9009a4f7a67464b5976d7547c860109e4432d50afb38e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000005245165295880ef000000000000000000000000000000000000000000000000000000000000001473b43834edf330b368b1de12389f3788a829d16d0000000000000000000000000000000000000000000000002da00bc3cd259e25a1f98522211a6e8e1d9509a5c3f7c470a6fa1cee5cfc7cc7224ea052942e2fb85b032e7d97cd53936d9667757165af2b1bbcbb94cda704065e47c7", + "0xf9024e8309c31c850b8b378a86831180e094a658742d33ebd2ce2f0bdff73515aa797fd161d980b901e4252f7b01000000000000000000000000000000000000000000000000000000000000006e0000000000000000000000004f7a67464b5976d7547c860109e4432d50afb38e0000000000000000000000000000000000000000000000000000000000030d40f5dc15dc0ddd284f0e1ed59df3a3de806ca0771a76524880088ea04398a621d0f5dc15dc0ddd284f0e1ed59df3a3de806ca0771a76524880088ea04398a621d000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000f40000000000000000000000004d73adb72bc3dd368966edd0f0b2148401a178e200000000000796f1006edd69db25f6d620a7bad3023c5d32761d353d3de9009a4f7a67464b5976d7547c860109e4432d50afb38e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000020ec54c4a1aa15bf00000000000000000000000000000000000000000000000000000000000000014fde6167c97e3523bd7672a348047b001a593e4350000000000000000000000000000000000000000000000002da0ca39bd5d52f9ee658dae4acb770db889a839e6fcd8fdc6f797d4e699462eeebea02d00594f1323677f846681461d85b8b36f3daeaafd8c10c53583086dce66c472", + "0xf9026e83017571850b8b378a8683048d9c94a6bf2be6c60175601bf88217c75dd4b14abb5fbb80b902046c459a28000000000000000000000000980205d352f198748b626f6f7c38a8a5663ec9810000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000006452aab000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000084704316e5000000000000000000000000000000000000000000000000000000000000006ef6fc95fe31194fc82c102ffbbf55d2f65e4f41cb100546db65e51a137a3a644f0000000000000000000000000000000000000000000000000000000000000014f6fc95fe31194fc82c102ffbbf55d2f65e4f41cb100546db65e51a137a3a644f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008281e0cdb9452df678fbdd337a2311be54d41bf69f18cea485f15e96fce7c3e5ab52f21b04e413046ab8aba282a10f91b09a30b8aa06818c8b3310d1eaf76a69591b1ff6372b6fc697fd08a886b126d62cbe27bbd090e2010f4044420b166e0b665e4c0feb3821cd5fb07c2c8059bd270e89a07c6b3dc8e87ee2d827090a16002ad31b0000000000000000000000000000000000000000000000000000000000002ea00fdb0a2ea5a9904a643b0bc868baa34606efe734e97dadbb55f1dd730f11be5ca03335ccc416a1c36baae8417e04d70365e7cedf4de6149241f8e26c246ffe6b88", + "0xf86f83027ea785094745553682520894e12c2c16f7f0e24a9c9d7ef09cd21afa1d11662188016345785d8a0000802ea0cbe7cdb56062c288711917889636a86449681ee48731df4c3be9aed130d31afda01998c983a185cbcbd773f49f67f3dff7bf117c6ad9772dd4c5614cbd519a9848", + "0xf86f831201e5850904d9693b825208945a0f6db1d257394d73d6f78ac7efd82de25207b888097cb99ba2e939a2802da0a894003e9129435956393d70a4ea802bc9a04f09578af3c84fb7f327740f8fbda057cec134e9fce157efefa7ab84487e4dc37e060bf4bc7f8a1f095b43fc9f658f", + "0xf86e831201e6850904d9693b82520894e3ea6d134349abf964f8f6e53ed7965218da1722879f33c341fb3908802ea0aac6713a1ec92812582251b4e2739cbd5df7455a4a269bc540356af0fa36ceaea05e16aa15d446d86102b9383ea59db5e24f7957a122aa73a1106106b435d204d3", + "0xf86f831201e7850787079ec082520894dd447f0cde89528824086895366c08679890c0b48801189ca0983f4a4d802ea0b6677ff3311a54883020840c35064eb8250b1deb095d594a64d00be7d98bca03a032330a1c22a86098737a861584315c4f627d87343e0116c451a25027469ee07d", + "0xf86e831201e8850a02c8703c82520894803868f83846199c70dd14b2be8beef86c3a50c4879f6255c2afb88c802da0da1ec99f36681006a328e7cf860d5e665a2dbe8e4fcf2461fae876f0d2b0671fa022499bd6eb18cb32796f8be7802ce3110109e2d4b6c3f2520a70cfb97e8f17a2", + "0x02f8770582073085067c95dd0085067c95dd0083033450944e0ba4e96813fea31c538efd015ac6646205da0a8803311fc80a57000080c001a0afd0a0f8ef968e09d624e4507ca8b53c308a9ec3315129eedd3cfbe0beeffdaea06f85a9a99bfc1dd3fef15e4dd42dff570beabe6e464fc6c52f7c3af6f896b43f", + "0x02f8ba0580850676584d72850676584d72830451f794e5e30e7c24e4dfcb281a682562e53154c15d33328801f7533714cac640b8449f8420b300000000000000000000000000000000000000000000000001f7532dc49b36400000000000000000000000000000000000000000000000000000000000009c40c001a0f82440a4555ea34292c330b42c07f8e94a6ff0dcee38581e44e5811eb9b7ee57a01744aea86365a26a35d53a5c4aff6fc494709d1e3d1a39113a19af9e9df21e63", + "0xf9012c8288b485059682f0008302e4b094c92470d7ffa21473611ab6c6e2fcfb8637c8f33080b8c458a997f60000000000000000000000005a94dc6cc85fda49d8e9a8b85dde8629025c42be000000000000000000000000deaddeaddeaddeaddeaddeaddeaddeaddead000000000000000000000000000000000000000000000000003635c9adc5dea000000000000000000000000000000000000000000000000000000000000000030d4000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000002ea07a10e69b3420a93177c94b31adc98782b25c48b6c58ca1b4f363d1222e5c085ba0772341cb648c66cfd34b7c01ea3bac96dedf1c02db62d6eac85086d14c48d948", + "0x02f8740580850573da8158850573da81588252089472f75c5c5754854790ac144ca0fe2d68ddafde36880f390034bc41454080c080a0f68a3bc319049e0f300b41528aa04d509818d82bfbefc11506fcd20f2100fa2ba0529840e6428824e1b738040001be19107a6973cd0eeb81d84c78adbf8191b3c7", + "0x02f8b30583014177849502f9008509d05c8c3682cc93945a94dc6cc85fda49d8e9a8b85dde8629025c42be80b844a9059cbb000000000000000000000000adf8b0883aba74232f26462d71fd54663b4d9fda00000000000000000000000000000000000000000000003635c9adc5dea00000c080a0a22a9c36768fa467f61a75d2d909725fb4c20c2c0022a6b4a589438ff4ae4ebca052dee5948a087a0476269eca17e31617b45584859c2e33cd28bf73a8035bb63b", + "0x02f8d30582019c84773594008508a927c5cb83010d72949c33d07e36fe6acedaadbdf30029b75531f62cc480b86423ff31a200000000000000000000000000000000000000000000000000121e6c485ac00000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000c001a0765a466be98729daf8e35765b81d2753c7a85120ea6a9812ed8164f138200be6a038aba37506bd7fb81fdc3e31872a7dcd94294e3d7b256e42c6ac7495f692f887", + "0x02f9015a0582013584773594008508a927c5cb830f4240949051dc48d27dab53dbab9e844f8e48c469603938872386f26fc10000b8e4deace8f5000000000000000000000000000000000000000000000000000000000000e704000000000000000000000000d436517fd3e2b7fbb0b234e4ee34f81dc1cf21a100000000000000000000000000000000000000000000002b5e3af16b1880000000000000000000000000000000000000000000000000002b26b8169c7af0000000000000000000000000000000000000000000000000000000000000645bcd43000000000000000000000000b47de784ab8702ec35c5eab225d6f6ce476ddd280000000000000000000000000000000000000000000000000000000000000000c001a0396e0f5e264ccbd579ef1e6e58929ba4b2b12931bef44d535188095f00188a12a015b5af32d3f6b4a198e741c0513ae8494348d0aedbc329c61ea076579aa81043", + "0x02f8750583107c83847735940085746a528800825208947a0fb632f86a8c8236ac8960b3a9cada3e7e0b30874c39bfa5033f0080c001a060a50ed1e2a9a4ab76be8747aec4d7320a236a148895ca11ad3e714093b1e0b8a009a62f99a6c4539d2426ee95177cf393ac34a5136e75e4adb58af86f685332d3", + "0x02f8760583107c84847735940085746a5288008252089473efc5030451e34c409df5f536a8636f4f8027588801c836f8e4e4100080c080a063addc95d1083ec4fac8b611276fc5de75ec8dd278f2aacd23541b4aec20cdc7a03b3d306f98f9cbdc4b908e8d741e566f9a95d004b2657533849690198f5006a4", + "0x02f8bb0583016c7784773594008505b6423270830289a89498aa442cefcaf0a7277d10889d07d04e90b37ea587038d7ea4c68000b84458891a3700000000000000000000000071383ff4de8b1b1da845c1e3fe40f03c054172fe0000000000000000000000000000000000000000000000000000000000000001c001a071c594533cc47af2cbeeb417896957de8b16ba690133eca554eb68100a6990b4a02f3a9e4be81fb19dd6e11efc36a0307cd8bf71a66b18aad58f41d7134f05eab7", + "0x02f9013105808477359400850650284c588301062694c80b3f9ce077749c43f945ab3fc6ec78c02ed4d180b8c4f242432a0000000000000000000000009735e6aeae7c78bb7f0f917ba2b086df12c0193c000000000000000000000000f0b443f0f6b8d01d3ae8a645af440c32ef3e61830000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c001a033f73bfae88b4c70f3a1d7b55c40614f878cfdb574ecc7eb1f2d0231131aa11ea0502a19dfc5144f31c47a16ab17217903974d0c1eb7f64299ea820c83f1191a05", + "0x02f8bb0583016c7884773594008505b6423270830289a89498aa442cefcaf0a7277d10889d07d04e90b37ea587038d7ea4c68000b84458891a37000000000000000000000000a2747d51e2b2b184644ae9809f7bcf162b4033e00000000000000000000000000000000000000000000000000000000000000001c001a0a99cb5469dfe2ecc9732e6eaeb98a2094502652b06f5f6802b4ae7f8e3f278afa04f9d5052e482d5f190cefd84dd1c494bc79eef3d0d3da7b0dc05eac6108d7e9c", + "0x02f8750583107c85847735940085746a52880082520894cd26f2f818b68ddf2d100ad916a7ca399ae69c85879078ce473b500080c001a0f1de870376b9668d21e5be9d8429cb007c8b3b9dd81257bd2ae7ff87e26c7681a020320692ac7c9f52c9cb84243d1b2ba2e60c51b7ffd75b24e87a957465fb03ee", + "0x02f9021905808477359400850628f9296c83039fa19458600af7c48b4f00b0280b49cb93086961f93de787071afd498d0000b901a484bb1e420000000000000000000000007266db7f988e2516063d0b7b85258f5e6b4019b40000000000000000000000000000000000000000000000000000000000000002000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000080ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000038d7ea4c68000000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a0ebe9546e67954fa446559645f9096f3a1f3395231b46a4a1ad48406ab03f9b3ca0347701a76959b057ff73bca4243606c59df7ba01727691bf30a30f5fd5004b04", + "0x02f8b9058202828459682f008506db6c477c82d57a9441e5e6045f91b61aacc99edca0967d518fb44cfb875df822864d68e3b84440c10f19000000000000000000000000c1bcbe74305a789873e983ac10a7e8452796b1260000000000000000000000000000000000000000000000008ac7230489e80000c080a01d83dddce075c9449a16425f3a853cfc67591f9fe2993826e306a6a1b116364fa05634587404125ff74cdfb7baf5e98c426c6ba621f01678a7601ab30669a178dc", + "0x02f8b20582015e8459682f008506db6c477c8255b894c02aaa39b223fe8d0a0e5c4f27ead9083c756cc280b844095ea7b3000000000000000000000000a86a38ad92035884396df4e8a6cf5eca75948493ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080a06225cc16f067c9b93b06ca8cbebe28775ba5f730c1158fc5f3fa6b3b3b60f0dea03dda7ad71554cfa91667fb690b7fefcd1901f548b66bd83ef1b7a7babedb9e3d", + "0x02f8b705748459682f008506db6c477c82d57a9438af6928bf1fd6b3c768752e716c49eb8206e20c87470de4df820000b84440c10f190000000000000000000000009b8442af540a642b5eba32d0f0ce0e9c0026283900000000000000000000000000000000000000000000000ad78ebc5ac6200000c080a00c7cc52393e38c044b369529cd58187b7675408718b6d3e8ddc52173ced60793a03628146aa7d6acb722d0b661567603c7c41d29603ad70697748ceae84ea21695", + "0x02f8b0050d8459682f008506db6c477c82b88d9438af6928bf1fd6b3c768752e716c49eb8206e20c80b844095ea7b30000000000000000000000009051dc48d27dab53dbab9e844f8e48c469603938ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080a06c6742f0250e1b184c2d850fe8684ba3b6bfb7a06d9d1d372d5682c77ab06defa02eb6a4b797de6cfb6345382d010aed46573073e4c820da4240864fcfd66f9726", + "0x02f8740581938459682f008506db6c477c82520894111a58a62c94272a9a5ab976de8fbc4bf7e8e6ad880de0b6b3a764000080c001a0a4adf81f3407a81b555f0c22b9e75d6d5437e9adad93cbb8f2b74b68c8da732ea00cb53a10d3e30da33897572dbb0911447b70d63ff20591ae93a6bd2b5902fbfc", + "0x02f8b1053d8459682f008506db6c477c830f42409438af6928bf1fd6b3c768752e716c49eb8206e20c80b844095ea7b30000000000000000000000009051dc48d27dab53dbab9e844f8e48c46960393800000000000000000000000000000000000000000000000ad78ebc5ac6200000c001a0e09aa04652fc52777bc5644439413753488440ef32d4e250f293b0d2919148ffa0374a90a5920598a6df34e99ca46d73d4416a33ddc99f8f517bc2ad882875e23c", + "0x02f8710581858459682f008506db6c477c8306957d9480fa9d2fe58b1254512ddd0ed1c07acc77ff5fe480841249c58bc001a0813e8a719ed801dbed69f258c4e9fe3c26fade4e04f74c82ac3615879b19aac7a0405b8ad7b28eb9d117127aaad89eb433d8b6b3364bcd30de2ad092dcd7c78011", + "0x02f8b705118459682f00850708346f6582d5869438af6928bf1fd6b3c768752e716c49eb8206e20c872386f26fc10000b84440c10f190000000000000000000000000cf3263d9c73c2dc762c1e07769a7e064c23d7650000000000000000000000000000000000000000000000056bc75e2d63100000c001a0b62dd0592e017f97c0e40f5f77b3f2be343e4d167f7f7a2dfa9fc49a7e5bbd76a0633a2ca068c0d2d96b75d45fc91a3accf3d45d171b5cc62eb32e90ae58aa855b", + "0x02f90158050d8459682f008506db6c477c830f424094889cd829ce211c92b31fdfe1d75299482839ea2b872386f26fc10000b8e4deace8f5000000000000000000000000000000000000000000000000000000000000e704000000000000000000000000e8a2d13d070b10b60d4e048583b887882b95bac500000000000000000000000000000000000000000000000000000000002625a0000000000000000000000000000000000000000000000000000000000000029500000000000000000000000000000000000000000000000000000000645bd6c8000000000000000000000000b47de784ab8702ec35c5eab225d6f6ce476ddd280000000000000000000000000000000000000000000000000000000000000000c001a02489664a24c8a792ca256f42c08ae6a38fee29483c58ea4bb8ac00234c7a2435a031b311cca5327c831b608d3a7a791e6ba9e80e45b2e0bc3e15a72387f6eba5ba", + "0x02f873051e8459682f008506db6c477c8252089410ad76b7f1c984593fc62b0f60882e533eb0dc1c88016345785d8a000080c001a05ad5a53c67721e244f2c5cd958c690efb348948d8153b3e465131768e826dad8a06c238584ce8aa9414468f608fb584bea9cf59935a258d41e183e96bbbbca6ec1", + "0x02f8b005148459682f00850708346f6582b4989480fa9d2fe58b1254512ddd0ed1c07acc77ff5fe480b844a22cb4650000000000000000000000009c33d07e36fe6acedaadbdf30029b75531f62cc40000000000000000000000000000000000000000000000000000000000000001c080a0ea4893969c9f5cfcdb3b3305c3b9af6cdb138b786973aaeb8562989f59533241a030c1352600f7f0882709dae400b940fda18a6800fc609a429892a6646bed04ff", + "0x02f902fa05338459682f008506db6c477c830358ea944648a43b2c14da09fdf82b161150d3f634f4049188016345785d8a0000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000006452a39c00000000000000000000000000000000000000000000000000000000000000020b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000020688f00d1c0dc4b79284343e00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002bb4fbf271143f4fbf7b91a5ded31805e42b2208d6002710dc31ee1784292379fbb2964b3b9c4124d8f89c60000000000000000000000000000000000000000000c001a0e19cf8cca7e65ceee15a7da899ee79b78f34f585d2f56cc470ee3cb575b1bff5a03f65fac2014f13e5922eb0c72464c83daaf440c776898ee6cdd42377f686a9ec", + "0x02f90159051e8459682f008506db6c477c830f424094d9e10c6b1bd26de4e2749ce8afe8dd64294bcbf58845871874b4b50000b8e4deace8f5000000000000000000000000000000000000000000000000000000000000e704000000000000000000000000fd3df177e50fe9540ce6cdfbc69a38604916a71d0000000000000000000000000000000000000000000000004563918244f4000000000000000000000000000000000000000000000000000044c9a9b85e72a4c600000000000000000000000000000000000000000000000000000000645bd6d100000000000000000000000081682250d4566b2986a2b33e23e7c52d401b7ab7000000000000000000000000000000000000000000000000002386f26fc10000c080a09c9b069187c56ed0f408d0fc30e26a4ee7834fec11658391ba41c3885ebdb452a07cc1c21cc89cc4a3888428c1e1a2f28901cb5bbcc4eae08539d7d03bd8e022d4", + "0x02f8b1052b8459682f008506db6c477c830f42409407865c6e87b9f70255377e024ace6630c1eaa37f80b844095ea7b3000000000000000000000000889cd829ce211c92b31fdfe1d75299482839ea2b0000000000000000000000000000000000000000000000000000000000989680c080a023bd490a5e701d64b23fa5ac72dd141d1129738cbec17a63f996a7684236aca7a01b7542ff9a0740476860ce539132450a0e202d7a1f01e37d39796b16d20a0eef", + "0x02f87205088459682f008506db6c477c825208948134643edb2fcbefacbde28f38e3d3b6e655240c88016345785d8a000080c001a0687c53a0c75d776e984d170fea68daf39c48bf461839415d01d2eee5decc0aea9fd676b0d58f35fbe02937d476614034a205df129cf8695a8aca2b113fa4a46c", + "0x02f8b005198459682f008506db6c477c82eb929407865c6e87b9f70255377e024ace6630c1eaa37f80b844095ea7b3000000000000000000000000889cd829ce211c92b31fdfe1d75299482839ea2b00000000000000000000000000000000000000000000000000000002540be400c080a0cb1693afc742c4e80cd335e04521ea99be49c33f228d55a0fdfef27b54a606e2a05561cff9a1d3dae67a1fb4fb4365ec5959ed0727042bbbb4204a1e4f34f19a3e", + "0x02f8b0050d8459682f008506db6c477c82b76194b93cba7013f4557cdfb590fd152d24ef4063485f80b844095ea7b3000000000000000000000000aa1603822b43e592e33b58d34b4423e1bcd8b4dc000000000000000000000000000000000000000000000001158e460913d00000c080a081148a1dde069df9dfb9ba3873256285a4ad47fff36e5bd2e31c03b053332f17a02a488e237c9fc91a0ab9f31cc65891e0a87201624463d5f5aa05a3b7c9b11b19", + "0x02f87405823a428459682f00850994c1c23682520894dab1a1854214684ace522439684a145e6250523387017dfcdece400080c001a03d474b1b610977f36a314b39e85da53f575a4976d4fbab1dd293df301e3baea1a03502ed39bae3890065f538f02ab1fc9ac383c3418a5fe7f70c23cb2e52d44775", + "0x02f901d2052d8459682f008506db6c477c83104bc1943225d9e0ffecb7f5ddf8efa568e250f90b91c27780b90164f2c78a5600000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004c4000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000068155a43676e0000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000326c080a093fee0d28d41590fea661cd1c16bd784d09320a38d95b70476c8063f5c83e849a04dd92bc2f4bc5c6b6d69c4985d263aeb1652e05cf0430eadd75135f9a6399a3b", + "0x02f8b805028459682f008506db6c477c8304521394e5e30e7c24e4dfcb281a682562e53154c15d3332872386fbbff09000b8449f8420b3000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000009c40c001a00a8ea9d65b57273bb2c30179b8de532c39140b867a9bd4a683e779cfdbcdcd57a04a38f5cdde8330d332e1aa43306ffa7ac5b7673d69be16812cc475f2b2de6d2a", + "0x02f8b005118459682f008506db6c477c82eb869407865c6e87b9f70255377e024ace6630c1eaa37f80b844095ea7b3000000000000000000000000889cd829ce211c92b31fdfe1d75299482839ea2b00000000000000000000000000000000000000000000000000000000003567e0c080a0cc160d3fba8e22961e288d1bdd994e9b3a0643e702dcd45d1f88b0ae73471167a009356e1e04a7a01ca00a7e91324a528f9d3c796c390ec97b08f8041ede2716a4", + "0x02f8f9057b8459682f008506db6c477c830270b4949c33d07e36fe6acedaadbdf30029b75531f62cc488015956cac01f44d9b884c5bb31680000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000015956cac01f44d90000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000271dc080a09595f9e78d4d1128a116ecafa5d2ff428da4c93c726f8164ea0b7854d45cab7ba013133498b69ef55b4f8b4a4a797fcd7a2b3fbb702d57b6d2e8c26d5a8f97be27", + "0x02f8b005218459682f008506db6c477c82b4cb941d8a8f8a0208f908974060eef0cc4e6a79d94f7d80b844095ea7b3000000000000000000000000cc9f513304317c0688bcf572cba35dbaa84f9c1e0000000000000000000000000000000000000000000000008ac7230489e80000c001a0098edc5cb61e061b57603bbdf8b2c0c18baca6a3d437c6741d5a56082f4e6764a06e6c2221d559188aeafaaf86e17a4746584f372ade9670b12e7e92dffe59a3fd", + "0x02f8710581868459682f008506db6c477c8306a1bf9432e724c4d163aebcefe707fc9ba8cf7db65caab880841249c58bc080a01db502881214d73ed072f6304fa472be3d5702b7a36fb49c3079518e06948346a0565d5bdd13255c52c8943aa20ce5b21009c5aafbff252f27e33e4282f078398b", + "0x02f8af05428459682f008506db6c477c82b73a945995d54a4bd0b79c4164086d24c70c3807cfeff980b844095ea7b3000000000000000000000000302fd86163cb9ad5533b3952dafa3b633a82bc510000000000000000000000000000000000000000000000056bc75e2d63100000c080a021827a199ae559b79e139fa772c5731a90cd87fda9b666f09e1240ffb71f09f79fdb707fe524434dd484cac7eeb616996ac4a3ea7939b38994908389e7510f9c", + "0x02f902fa050a8459682f008506db6c477c830357a3944648a43b2c14da09fdf82b161150d3f634f404918802c68af0bb140000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000006452a37800000000000000000000000000000000000000000000000000000000000000020b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000002c68af0bb1400000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000002c68af0bb14000000000000000000000000000000000000000000000000000007177137c5d34f3100000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000002cdc279823190daf56860239e5f2680a50e3d0ec001a07c692da1f89ecfd7713d3a249d01ad14ada9ff2ca63effa27a7823537a25a934a0532f1325cf0b42bb0b7a9c0f3dc950496a864bf21cdf81478bd7275a70563276", + "0x02f9019a050e8459682f00850730c4bce4830246da941908e2bf4a88f91e4ef0dc72f02b8ea36bea2319880508314a13a34b23b90124eb672419000000000000000000000000359477a7fb0ec693c0efe6a810d94c60185921ad00000000000000000000000000000000000000000000000005068e5cb5d6ee2700000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000ab5b400000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000359477a7fb0ec693c0efe6a810d94c60185921ad00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a06821f32ed809e5215775e451bec35a13dad74f74a7ad3cb73decf617268c31fba042dd4544ff49f13b24f4adc74bf17db56a64822688b3cce701a321fc433af866", + "0x02f8d1052a8459682f00850708346f6583031812947f33ca8ff46d7dbb0aa650bef24175367e3d831780b86437e8a147000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000013f306a2409fc0000c001a0a67c358f41a73a66aaa8fa375389a632f864a14f713c5af0380011ff14577d97a04e64fc2e6fa3159356fce48f69e03cd759c780a04d313912a19b0357d4959ff7", + "0x02f90377058201278459682f00850681a1e1e88303a3f9944648a43b2c14da09fdf82b161150d3f634f40491835d8275b903043593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000006452a39c00000000000000000000000000000000000000000000000000000000000000030b010c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000005d8275000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000005d827500000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002bdc31ee1784292379fbb2964b3b9c4124d8f89c600001f4b4fbf271143f4fbf7b91a5ded31805e42b2208d6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000c080a093ee3afe5665ed05a762419ad4f345fc0dc40f79f76db869c1f456ca820f6f45a07e5a99a96f8c6d96ec3ad2dea9e4909f2d25c008a7a568105079193365ac52d1", + "0x02f8b705018459682f008506db6c477c82d58694b93cba7013f4557cdfb590fd152d24ef4063485f87b1a2bc2ec50000b84440c10f1900000000000000000000000016b5d21c55c9b8c5d19a61c3fc84bab298487f9e0000000000000000000000000000000000000000000000056bc75e2d63100000c001a04dd1bf5af9dcfd34115102f45118a6a6404623ca385693aa2ae2015bc7a6333fa049cd2c6680ce68636ad72673a98deae6c334241d96eb078213a22f9b28ab7be4", + "0x02f8b8050a8459682f008506db6c477c82d5869438af6928bf1fd6b3c768752e716c49eb8206e20c88016345785d8a0000b84440c10f19000000000000000000000000a921890db440b6ea9f77b3ca5112e8ee39dc9cb800000000000000000000000000000000000000000000003635c9adc5dea00000c001a0d00326bd29a4fe224a722169799f2f0e563f33e2d45d3951290ff85d9749b8d1a042bc1a0e4a804b2a5bbbcd217d4a0654fd494709220ac84d843d79034619c6db", + "0x02f9015805128459682f00850708346f65830f4240949051dc48d27dab53dbab9e844f8e48c469603938872386f26fc10000b8e4deace8f5000000000000000000000000000000000000000000000000000000000000e704000000000000000000000000f444c6e86d026ece075068c859e4c91223e4901f00000000000000000000000000000000000000000000001b1ae4d6e2ef50000000000000000000000000000000000000000000000000001af8330e21ccd6000000000000000000000000000000000000000000000000000000000000645bd6a5000000000000000000000000b47de784ab8702ec35c5eab225d6f6ce476ddd280000000000000000000000000000000000000000000000000000000000000000c080a08c3e0da7c2eda89afa71eccbaa3f85f9c111053957f9369cb5b195eb2d2d9b0aa03e901d5f9d762aff9667cfc7ca77b06fdfc4f97fa0d8826f58a5a87390241060", + "0x02f8b0051c8459682f00850708346f6582b76194b93cba7013f4557cdfb590fd152d24ef4063485f80b844095ea7b3000000000000000000000000aa1603822b43e592e33b58d34b4423e1bcd8b4dc000000000000000000000000000000000000000000000001158e460913d00000c080a01587bcfc475e453f0c6947d98ce55aaa89d4635b726841207239874a8ec0a658a03eea6b96ce25510d0c72c00fef981e30abd3c93bb136745850e555a489e2cc81", + "0x02f87305808459682f00852e90edd00082520894fd6140999ca02a0ee7b75856009c6f219627892c880dd1cad2f355800080c080a0e810344b0f578a0fd6373209cc6b37d5424ca9905c45fc67b3ac74c48560bce7a0555d7b80b69fca438078567a373fa87d9c829c94586e995bf364a9711604174d", + "0x02f9017b0581858459682f00850681a1e1e883061a8094805fe47d1fe7d86496753bb4b36206953c1ae66088016345785d8a0000b9010485ff842c00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000080383847bd75f91c168269aa74004877592f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000557300000000000000000000000000000000000000000000000000000000000000014a91e492b00c00b6a05186e85754133d2790ea009000000000000000000000000c001a05fb9cb803bd15acd3c8c3a79bdc3dea9c7597a60436134e60eff5ecd0424a4c6a0431d678c7f5d9b3f842b2bc42f75dd12c3f59ee2ca488910697a1c882db7e4f4", + "0x02f8d20581e48459682f008506db6c477c8303837f94779d1b5315df083e3f9e94cb495983500ba8e90780b864e7a050aa000000000000000000000000b613e78e2068d7489bb66419fb1cfa11275d14da0000000000000000000000001643e812ae58766192cf7d2cf9567df2c37e9b7f0000000000000000000000000000000000000000000000004563918244f40000c080a07e17122998ee3bc4c9a9003fc4ed855dc6939e352e1f87f84e930063662025b3a034825f83814642d191e123f66f8bf32d2216e31376112737bcc728425ad88724", + "0x02f9017b05818b8459682f008506db6c477c83061a8094805fe47d1fe7d86496753bb4b36206953c1ae66088016345785d8a0000b9010485ff842c00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000080383847bd75f91c168269aa74004877592f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000005573000000000000000000000000000000000000000000000000000000000000000143149e634d632adb3cf9eb12a04178256197c6f87000000000000000000000000c001a0d55714e6663daf999667ec7711f20c4df0507fe53525f1f27d237c29788b5e95a01c1f4b071fb2643b31091b5a440a1a9979d65e125ea9a2e53b192100029d254e", + "0x02f8d905658459682f00850681a1e1e8830235b8947e639163e1a98685c88cba719c9456087922af39880de0b6b3a7640000b864b1a1a8820000000000000000000000000000000000000000000000000000000000030d4000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000c080a0824ab32af5f3f1358a9ceff87a44c97e3a4e403effdc18ee04f1e697bd108c41a053c9ca6f210094075d3ab6fbd7d69dbbcf8232ffb853af143bbeefdda9034cf1", + "0x02f8b905058459682f008506db6c477c8304520a94e5e30e7c24e4dfcb281a682562e53154c15d33328801634581adb99000b8449f8420b3000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000000000000009c40c080a0e019468d950874d4ad9b463d7eb4a401b201afe6e607477aad542cdebe7b69dda00ca8b0fb0dc025776da4cf0e68d4900b0fec6c40412e9dd729014215cd5c4899", + "0x02f87305218459682f008506db6c477c830207ed941643e812ae58766192cf7d2cf9567df2c37e9b7f87470de4df82000080c001a04533f11e0ad971fa4de8f166c7d91e815a4c4c5fd36d94e0e73fbec8d7234447a01dd047339663cfb15041a3350a9a3a73e388274917159f835ba9f8cfc66249a2", + "0x02f87305018459682f00850681a1e1e8825208946691e9ba7993a588fa007b4afe494367e87d75448802acdd0e5b2a36e180c080a0aed983a6f7ec44f1b982d61f1ecb0a79fae0c40701ae23246df7933cdb1af65fa05e5a0348d5277d473d4c10e84caf5f152ffad6009933626a43cfdfee7af8a3ac", + "0x02f87305808459682f00852e90edd00082520894ba5ba44f02f30502f50c0acc0ec394fbea606c5a880f084ca934b4000080c001a03df56496bdb85d24243f5ca947aea07e7cc70b10ad3169b74552da9f2e8ea8a8a06a86b08ec4f4b258d30dd553291a5ab9306d6f9a9c6791de55844d02cc43aca7", + "0x02f8b2058201278459682f008506db6c477c82b76194b93cba7013f4557cdfb590fd152d24ef4063485f80b844095ea7b3000000000000000000000000aa1603822b43e592e33b58d34b4423e1bcd8b4dc000000000000000000000000000000000000000000000001158e460913d00000c001a087b4f769eb229f070890638cea9271b76c2fcdf1388d56deb22d9e03e8db5968a0382222a283078774f2fad7b84c85d4baf3209ef9dae228e0135f21ce87e3778a", + "0x02f8d105158459682f00850681a1e1e883028e9694779d1b5315df083e3f9e94cb495983500ba8e90780b864e7a050aa000000000000000000000000b613e78e2068d7489bb66419fb1cfa11275d14da0000000000000000000000001643e812ae58766192cf7d2cf9567df2c37e9b7f00000000000000000000000000000000000000000000000010a741a462780001c080a0f0e3cc799d3bb9da78972f3b7f73daa1f332e787dd7c6570e7e615cdd9c67944a037846851877549bd21b5a2478f365c8299fb81c20aff97e92a8e00d61b75aa42", + "0x02f8b005198459682f008506db6c477c82b88d94b93cba7013f4557cdfb590fd152d24ef4063485f80b844095ea7b3000000000000000000000000aa1603822b43e592e33b58d34b4423e1bcd8b4dcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080a0528cff0c28a944d58b911d49ee8cb816744adaac559c76bfdf545190fcc6ae11a011d4c5a42cacb1c2722c3566901f09a2c473a19507bc61ad0d455c38360732ab", + "0x02f8b905018459682f008506db6c477c8304520a94e5e30e7c24e4dfcb281a682562e53154c15d333288027f7d152bc19000b8449f8420b3000000000000000000000000000000000000000000000000027f7d0bdb9200000000000000000000000000000000000000000000000000000000000000009c40c080a0374352eaf857ed02eb9cb2d4a46bd834cdb40d7db6323978c8d4135e348e8a70a0175ec6659984dd453c95e4c7f41a55e34461e20eafb59577eeb143d5b83ced17", + "0x02f8b0051b8459682f00850681a1e1e882b7619438af6928bf1fd6b3c768752e716c49eb8206e20c80b844095ea7b30000000000000000000000009051dc48d27dab53dbab9e844f8e48c46960393800000000000000000000000000000000000000000000003635c9adc5dea00000c080a0665514a42625fa77d35012d7685b23a168cd2552477786b85520c929956dcfa9a03350ec27ec1dc0d58bc22224797d36eff7ebbd964574152e51d1487aa313a621", + "0x02f8b705018459682f00850681a1e1e882d57a94b93cba7013f4557cdfb590fd152d24ef4063485f87b1a2bc2ec50000b84440c10f190000000000000000000000007d16864b2171d7ed61b8af37001c8783fde95d690000000000000000000000000000000000000000000000056bc75e2d63100000c080a06a8f40db2d2f628f30efa23b3935a1ca71adaefe3994dcbcd6c463a72982d75ea03ac10ce15c8edf86fb7d7ef523df8f48e48157a820c89c9e84feb477ae1cbea4", + "0x02f9015805068459682f008506db6c477c830f4240949051dc48d27dab53dbab9e844f8e48c469603938872386f26fc10000b8e4deace8f5000000000000000000000000000000000000000000000000000000000000e7040000000000000000000000009e23345d86b1799a2617acb1b76317e32ccac96200000000000000000000000000000000000000000000001c30731cec0320000000000000000000000000000000000000000000000000001c0c5e0eb2831c000000000000000000000000000000000000000000000000000000000000645bd697000000000000000000000000b47de784ab8702ec35c5eab225d6f6ce476ddd280000000000000000000000000000000000000000000000000000000000000000c080a0142ad1e8fba0c6ced006755bc06e67153516725ff01b6cb676348d9a6b85e4efa0492faab0cc4024830a3ffaa698b0b20e9bcf9b19a4fcd5301f4c2d9e4732d88c", + "0x02f87705078459682f008506db6c477c8303edce94a9a6a14a3643690d0286574976f45abbdad8f505872386f26fc1000084d0e30db0c001a0c8e13490e357f659bf721493dfc6bf0246436fea20d7cea0613f8db9bd4220aca01b5da1bec38c1941a946997cd6f88ac7dc1bf0ac815ae5d2ff563a15e54d7537", + "0x02f8b805819d8459682f00850681a1e1e882d58694b93cba7013f4557cdfb590fd152d24ef4063485f87b1a2bc2ec50000b84440c10f1900000000000000000000000034401ee226b1fee337887a085dceb1326d85d2fa0000000000000000000000000000000000000000000000056bc75e2d63100000c001a020d417b9fb066b638bdf5a8c01a7b049fd1ae721f187aeee6870869d27b76075a017292f7a4d9d1bd1d082c65b9d0d4620c33ebf92a03d63ad061ab5dc28f30758", + "0x02f8b005068459682f00850681a1e1e882b73a9447a4357315e1d3ab3294c161c3a52e8b0d3a410980b844095ea7b3000000000000000000000000302fd86163cb9ad5533b3952dafa3b633a82bc51000000000000000000000000000000000000000000000001158e460913d00000c001a087f5be5a2f09a31f3e24881bfdbf0163651c4e85b2f5eb51f85619d677d6d456a01317e0fd5dddfd596ea09ae6c23529a7acadcc4ad2f6e4933382bc6285c3d213", + "0x02f87405829d9c8459682f00850994c1c23682520894f847a6252b6700415d2996a803002aeebd5d1ba087038d7ea4c6800080c001a044d04a2fb4e5d0465df809fe2a3acfd56b563d79dd607a1a307d12b995f75197a040cf1e56e100d34ce3ef190be4a4c5a843f05d9f36e73356eb1625c3114ae224", + "0x02f8b80581e88459682f008506db6c477c82d55694fad6367e97217cc51b4cd838cc086831f81d38c287b1a2bc2ec50000b84440c10f19000000000000000000000000fe25e9792547cc3a864fc3bc71337ed1f3f71afa0000000000000000000000000000000000000000000000000000000005f5e100c080a0a1ed59edbae7200c6d96e5991b7fdd899043b812f0164770fbe871d5a53ffbb4a019db4edd6c5ee2590f5370a91d4f411da7c7fa526b42f4663fa63372fc8349e2", + "0x02f9013105148459682f00850681a1e1e88301998994cf45a233fb21a77e67a0fc5d3e3987fa9cb59e8380b8c4e79b9db8000000000000000000000000c5bbac81754d2ccfdde030f6aea05d881752f2f8000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000e6a61636532392e746573746e6574000000000000000000000000000000000000c080a0f74c21e3ce66a4b0c6f49c6cb5f773f5ae6af006ebbb52752bfc011294ecdbcca0288a775e0899b93f8f10bf465a8819d7833b1c06766b24d2dfedf5a3a1007a77", + "0x02f8b7052b8459682f008506db6c477c82d58694b93cba7013f4557cdfb590fd152d24ef4063485f87b1a2bc2ec50000b84440c10f1900000000000000000000000097d50af0e83488ce3d595267cd95525b3aada9f10000000000000000000000000000000000000000000000056bc75e2d63100000c080a0a5a46dd0b6ef4a14cdebf9832f093f8802cdfcba65e021c278674a6250bc86d7a042fea4394989a820339a6d1549b3ece4c4a3c4a3ea75a3243bf7bb1cdc9b25e7", + "0x02f8b005318459682f00850681a1e1e882b4a49480fa9d2fe58b1254512ddd0ed1c07acc77ff5fe480b844a22cb465000000000000000000000000fcf56865e9ec7155e756d69d2d8d1e2f5ce89f860000000000000000000000000000000000000000000000000000000000000001c001a074ade40511311ec0d4f298518556f24c27dbe21e3b770fe63cd569db6246fbf2a045bdd63a468f090dde0c8a381b15f85f3d24b8be0dc3309948a42d271dcf58d9", + "0x02f9019905148459682f008507d2c286af830246da941908e2bf4a88f91e4ef0dc72f02b8ea36bea23198748f01c0c428f23b90124eb672419000000000000000000000000c47b195587fa6c50306abc5ebab29c255d7f8a8100000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000b54a300000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000c47b195587fa6c50306abc5ebab29c255d7f8a8100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a050e1ee5b43197b8a26d7fbb90c1026c0dd15b5d651e8dea447d9522dcfe72e90a0387817200f3ce84e00aecbb0ca6529b81c39dce36e355e3ee9ea379e8d085099", + "0x02f9045a05158459682f00850681a1e1e88306243d944648a43b2c14da09fdf82b161150d3f634f4049188016345785d8a0000b903e43593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000006452a15000000000000000000000000000000000000000000000000000000000000000030b000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000eeec9b06d6dbf868d50f0f46a6389b9778344382000000000000000000000000000000000000000000000000016345785d8a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042b4fbf271143f4fbf7b91a5ded31805e42b2208d6000bb811fe4b6ae13d2a6055c8d9cf65c55bac32b5d8440001f4b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003dc7cd971fbf83500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000002cdc279823190daf56860239e5f2680a50e3d0ec080a0b6f1e816bfd64bea9ca2549683d6be15cfee37a927b45e9888a01db99a1c178ea0697cb263f0d4cf2bf36aad177778b6aa770f8fae522dacdb7772bbc197dadfb7", + "0x02f901590581e18459682f00850681a1e1e8830f424094d9e10c6b1bd26de4e2749ce8afe8dd64294bcbf5878e1bc9bf040000b8e4deace8f5000000000000000000000000000000000000000000000000000000000000e7040000000000000000000000001c52216e2c08b7c86f27fe74d7d6206bb0648794000000000000000000000000000000000000000000000000006a94d74f4300000000000000000000000000000000000000000000000000000046583da915ea6900000000000000000000000000000000000000000000000000000000645bd64600000000000000000000000081682250d4566b2986a2b33e23e7c52d401b7ab7000000000000000000000000000000000000000000000000002386f26fc10000c080a08ca38d97aaf6281ad1befb36b7bfdcbbad589923d7a1f023f421c13e1bbed4e0a001805871ab16d6a3a9d7e6e0d2e6e3593d6340451e22c61371baa3d660cf64fe", + "0x02f901b2054d8459682f00850681a1e1e883061a8094805fe47d1fe7d86496753bb4b36206953c1ae66080b901449848a6b3000000000000000000000000cc7bb2d219a0fc08033e130629c2b854b7ba919500000000000000000000000000000000000000000000000029a2241af62c00000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000557300000000000000000000000000000000000000000000000000000000000000014027aab1d6b13885ce2ada9a70e6cafa31271fd1d000000000000000000000000c080a0936a17994b8782e7511badc8636253e064e58bc8d7786d0924620f353c8c221ba06a971b60050f102cee127c054cf0b2a7a222744d6651131027ba46d5f15e557c", + "0x02f9017905038459682f00850681a1e1e883061a8094805fe47d1fe7d86496753bb4b36206953c1ae66087b1a2bc2ec50000b9010485ff842c00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000080383847bd75f91c168269aa74004877592f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000557300000000000000000000000000000000000000000000000000000000000000014bbaec5458f67197de96f2ca3d94d634316c804a9000000000000000000000000c080a09c3d11c59094f5f72e3fb71859533a668bd93d9969fe92beeb32e0360b2d17b2a05c14bfb1febbc9204b9e8696257999251ae4299ea661ba2d3f17af5ad3ff80c7", + "0x02f87305018459682f00850681a1e1e8825208946691e9ba7993a588fa007b4afe494367e87d7544880142e9f93b69950a80c001a0ec8fed3856af4ba519f0fa5e35c8aaa4c80ecb55254697d957c0c992b29d9387a07769ee78933c3f5faf9a1f37327a5d5637b3f67ff08e1a4ce2c37bfc362fbef4", + "0x02f8b005448459682f00850681a1e1e882b7619438af6928bf1fd6b3c768752e716c49eb8206e20c80b844095ea7b30000000000000000000000009051dc48d27dab53dbab9e844f8e48c46960393800000000000000000000000000000000000000000000003635c9adc5dea00000c080a0c4b091cd5c91856c1bf3fe5490509d3440b6eeff21df88779789237a8b90419da062c10773737d28a96670fa11fcbad7b4dcc5bf5c9b3a1402e3d2a8468a5b0327", + "0x02f8b0051d8459682f00850681a1e1e882ea1094932ca55b9ef0b3094e8fa82435b3b4c50d71304380b844a22cb4650000000000000000000000001e0049783f008a0085193e00003d00cd54003c710000000000000000000000000000000000000000000000000000000000000001c001a0a5f6e45864847b75839ad46e8b9b9422ccb861e17569901058e9c5c7830132b3a019a2532311e0ba050d73f0bc7c63056d8866dfd9f0429414e1ddd2b4d190343c", + "0x02f873053d8459682f008506db6c477c82520894f32680cb72981e94265cbdd7e0a9a510a2a13d9c8814d1120d7b16000080c080a0285f026346e63afbc0ae3bdf87bb7ad76280ef1dabc0f221863b5a0e761f7529a01a8302068397e19bb2c25f6737f5c1ec7e4ee99584566129541f6409ca967002", + "0x02f870055f8459682f00850681a1e1e883011e6e94b6806650a5345da2a7c119648944a52e7faa0eb180841249c58bc001a0cfaae544330304abc1a7b244709bdd95466670dcfb751131a738b55b21cd2de8a05eff056d772e15f8a0b17d7ba3319c2dbc3e0faf702da9b9cc17548646715b49", + "0x02f89605238459682f00850681a1e1e8830143f694fca08024a6d4bcc87275b1e4a1e22b71fad7f6498607780adec89ba42424401fc2d21c43c2c06181c9fc2e195c9fc98c50fa9b950bed6f9b0ac441c7733f5efbc001a03207f88fbdec768ba7507ffae042c87cd584df18230925b0880f86e30c8b9bdca060425536e71f32569f81fdecad0f241d29482da0ed10453a5bca86e1aafe386a", + "0x02f902fa05058459682f00850681a1e1e883035a13944648a43b2c14da09fdf82b161150d3f634f4049188017896703a310000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000006452a3a800000000000000000000000000000000000000000000000000000000000000020b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000017896703a31000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000017896703a310000000000000000000000000000000000000000000000000000009ea22ceba1457000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002bb4fbf271143f4fbf7b91a5ded31805e42b2208d6000bb8178e141a0e3b34152f73ff610437a7bf9b83267a000000000000000000000000000000000000000000c080a0147339ebf27e4d658d4374b924908040bec510b3b46869a30a9bd2d86100a08da018a58049310e8f225899ce7d5209a8dfedd470d03549e4f692c5394a00070819", + "0x02f9015805308459682f00850681a1e1e8830f4240949051dc48d27dab53dbab9e844f8e48c469603938872386f26fc10000b8e4deace8f5000000000000000000000000000000000000000000000000000000000000e704000000000000000000000000be39ad73b0b4a536a40dd803d12c0c95970586d90000000000000000000000000000000000000000000000004563918244f40000000000000000000000000000000000000000000000000000450ac0242d91800000000000000000000000000000000000000000000000000000000000645bd6a8000000000000000000000000b47de784ab8702ec35c5eab225d6f6ce476ddd280000000000000000000000000000000000000000000000000000000000000000c001a04a6ff5eca960a9e66be70e47fc535555a45249d49d696f79c36d8dbda26c7d1ea02508b1ae55e5c1924a11c62ca2466a157a8f27c6c42ef7591bc6e59325324d1c", + "0x02f8740581e08459682f00850994c1c236825208942fdd7d8bafec4e7f6ca9ed3fee47748bcbff7ad68802c68af0bb14000080c080a04c1f9b05a05c7f026b883a4ab869cda4045d7cfc3d3a5eef1ef9f30cce7fa2f8a0076aca9ea2ea1c804c1820784d9686a67f81cd08b0104b4814303dfe54ccf059", + "0x02f8d90581da8459682f00850681a1e1e88302bc9294fcf56865e9ec7155e756d69d2d8d1e2f5ce89f868711c37937e08000b86437e8a147000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000011c37937e08000c080a0f7cb632fa397ea515b1ed6e64159f21f8a0ee0467b16e3676621d12aa1e20d39a054db860c11259293ecc48578fceafb37b80a2ef4fafce474e3825c85b54e3a01", + "0x02f8b90581898459682f00850681a1e1e88304520a94e5e30e7c24e4dfcb281a682562e53154c15d333287038d87f4f61000b8449f8420b300000000000000000000000000000000000000000000000000038d7ea4c680000000000000000000000000000000000000000000000000000000000000009c40c001a0da0bce3e44b5a31a70dddcde96f0a508520ec932b7aa38df34547e674316548ca06991a879251849043a801ef4fdaf56ee086f6ce623f6c2a157895e128233c7cb", + "0x02f8b7053f8459682f00850681a1e1e88292ba94b93cba7013f4557cdfb590fd152d24ef4063485f87b1a2bc2ec50000b84440c10f19000000000000000000000000e4ebcff8ae18b41975d6abbdb3af1ad4567fb1760000000000000000000000000000000000000000000000056bc75e2d63100000c080a00fcc8517181f6bf6e34a8d74e59ace2cbb57e423aedf2f5f0b92efab75ec5024a07006e7b7682ddea6f624c061538115c89b885d88c2c1d4d4e8ede601606b3f49", + "0x02f8af05038459682f008506db6c477c82b3da94d87ba7a50b2e7e660f678a895e4b72e7cb4ccd9c80b844095ea7b300000000000000000000000078fc3ce997ebecddac5dffb9e7388453cc8952bc00000000000000000000000000000000000000000000000000000019debb4fc0c080a08cfc1fa2c53b004ae1b342b881583cb89deec6181343981ce455a338cadc65ff9f93b3bf311664b16a3b79537013722202e9365ee144b203a7e477dfcc0f7188", + "0x02f86f0502843b9aca0085050db0c92c82d36c94525aa8524d7612be86463453636fa527aebb7b5480844e71d92dc080a08456a0776bf97b51b09b8545d4f09da6de8d85060b61b12285ebb346251f1b4aa007b81d83f164a52ee3b7271dabdf785dd30460788146811e6266648a45fd5913", + "0x02f901370580843b9aca00850ba43b740082e43394e93c8cd0d409341205a592f8c4ac1a5fe5585cfa8740b1e6055c2000b8c4e9e05c42000000000000000000000000fcc4c549f2fc1624b8e7ffe9129fe5dba34bda060000000000000000000000000000000000000000000000000040b1e6055c200000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c080a01e8adc7c62679fe810b2c7b447c9557063d1337ca851728ed3cb7961ee625bdba02bb97fb16d56be95a18e4e80a3c1ecf73fa3e2c42fac0ea4b13fdab509c4e8c8", + "0x02f901370580843b9aca00850ba43b740082e43394e93c8cd0d409341205a592f8c4ac1a5fe5585cfa8740b1e6055c2000b8c4e9e05c420000000000000000000000008fbbfe10b812fd58a30dfeb7651a605902dfc2d50000000000000000000000000000000000000000000000000040b1e6055c200000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c080a09ca3679989879ac543351db76fad65f6003e79c7d6a0933b03a76ebbe800b744a078c3e8641019ff2779650cdb6c5547845989e1dc20f59c5a9dd4faadcbae3f51", + "0x02f901370580843b9aca00850ba43b740082e43394e93c8cd0d409341205a592f8c4ac1a5fe5585cfa8740b1e6055c2000b8c4e9e05c420000000000000000000000002bff746b11ff2759d1426ef4652133647b839c020000000000000000000000000000000000000000000000000040b1e6055c200000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c001a0cb0fcdceadc8ed2f9b0387921808153085994dfef125a990565921f7ce543ed9a032261b327ce30d9a87bff6e99c66ab056b684227fc691d2f8ae79ce1263ef49c", + "0x02f901370580843b9aca00850ba43b740082e43394e93c8cd0d409341205a592f8c4ac1a5fe5585cfa8740b1e6055c2000b8c4e9e05c420000000000000000000000007ddeca5ceef309a7e3e41e305c03d8f9fbe75b9b0000000000000000000000000000000000000000000000000040b1e6055c200000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c080a0d4774b09786fd47179c617ded5b1002593bb7e683ef2131dce495a4b2c32da51a0664ea741589fff7e7a276d255b58d6b6ed163f75b7ee87d0488ee9d7bd16f7e5", + "0x02f901370580843b9aca00850ba43b740082e43394e93c8cd0d409341205a592f8c4ac1a5fe5585cfa8740b1e6055c2000b8c4e9e05c42000000000000000000000000745b4cfd9e596329f884de779c6a854954061e4f0000000000000000000000000000000000000000000000000040b1e6055c200000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c080a04a8c40f31f54f1a2fc9262cde2058d8cbca457cea7e8d78667d0abdb7870f374a028efc22ccadff119eab2ddd00293ae04c04184115243599bdaf0ab639c53975f", + "0x02f901370580843b9aca00850ba43b740082e43394e93c8cd0d409341205a592f8c4ac1a5fe5585cfa8740b1e6055c2000b8c4e9e05c42000000000000000000000000c5e484a71c195efa18a84e2f9cc635330ace95640000000000000000000000000000000000000000000000000040b1e6055c200000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c001a067c47b9dcb54808759af8bee1e1810f8db0bf7e25b334ad5b46ee80507c44ef3a06aff44242ce8bf40db87d23ee77aba41705e7f4abf4675c353aa026dfd0cb268", + "0x02f901370580843b9aca00850ba43b740082e43394e93c8cd0d409341205a592f8c4ac1a5fe5585cfa8740b1e6055c2000b8c4e9e05c42000000000000000000000000073fd5263516877b570cdeaedbd2ae5c87e620e00000000000000000000000000000000000000000000000000040b1e6055c200000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c001a0576f79ba8919675d4a9a49688b076e8cf2933d899075911e2dfc2f6ae7901b86a03d86ebdb3d89042ca66aa6dcbecf41fa1eafd848d39551bae41f92249bc94115", + "0x02f901370580843b9aca00850ba43b740082e42194e93c8cd0d409341205a592f8c4ac1a5fe5585cfa8740b1e6055c2000b8c4e9e05c42000000000000000000000000dd88071f8831a943ede5fb85e8cc7afe8f5600f40000000000000000000000000000000000000000000000000040b1e6055c200000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c001a0393954e11c2b018d00279d6b1a3abbe9c14d258e38cd039ed1d0ede7af85887fa0055f90d03ce9002a6b9a084c271bed62e15b9187868e49821cc5623cd066f225", + "0x02f901370580843b9aca00850ba43b740082e43394e93c8cd0d409341205a592f8c4ac1a5fe5585cfa8740b1e6055c2000b8c4e9e05c42000000000000000000000000edd16349db7363ac220e9fbf950c0d10077be0560000000000000000000000000000000000000000000000000040b1e6055c200000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c080a0463558d61223a0b40414c16a6e46c80f3b5c0f38682947974fe57d52919d6e87a00531d35e294aea644b9b0cf5382c12f32238bbb5cb0420f88b2f015c0b6e2d56", + "0x02f901370580843b9aca00850ba43b740082e43394e93c8cd0d409341205a592f8c4ac1a5fe5585cfa8740b1e6055c2000b8c4e9e05c420000000000000000000000000ffbeb141052ac78cf79b69cebb1049730b8c8ff0000000000000000000000000000000000000000000000000040b1e6055c200000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c080a06b15d2ccf810b0676c8a38f6bf7689a7c69d98d4de58542686e357134a8fd307a00bc0293f67af297b845d257cb18b43038b25d4844b2c9176139139ebfdafac7c", + "0x02f90654058205ea84389fd980852a2b97e00083062c9294cd9dcc7b0a483a91ace0a7f65bab7ce0f5a0c20780b905e4377bb7700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000005645322843000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001e0235d3fdc4e07785d8608fe555e4487b0fdf592850a2be90c848bd229af933e691f9fc05952bf64866dbdcb43d67d8374596b18de5d7661b47045bc76bcb288101115e379a2241605f347253e7174c5018cdee8aef13185dd490e198071cca58024101d09ff5b3a728c8b3c80579f84a7d2237d93063b446227d826e653efd88e0a49f715684e5427395ab4954023822c46ba515550882d0ef7fcb4495bb33bd808646b86034b4d95b74cf15f618fabe14d5558a3961fbc88c4e5c9c88fe9064e1aeaa9909ff455fcaafeb40a52736fb17cd0d1f355eaf4cc133df0136ad6232315776249e89676b5b7f6317db437fc2d63bdc90a7b7230e8142ad67eeaf99a460000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000000000000247082b6f85455da807ce883e5520c72340dbcf7c7929cfdd1cd1484b7dbfd2f37fafdde44b0d815089473949f365028abe97ae9ce0179efb5b68985b2b0bc839c922bbaa9a523b7d63762fb4f641195ac902164df3135a39aeff22e717d136285bd86d88438f2a142d5dd06f1451c60854db9c9ad90e79064eff12271713032491c6e084f505870dd63f83b1d17d16b0f45abc81db64529c680012000000000000000a000000000000a400000027000000005540000014ca616a5ac9233c800000014cb34bbffc67326400000014ca9ed50ec788956000000157560e1a0387758580000015759e68ae36dc0cb0000001574cb2bab00000000ea400000027000000005540000014ca9fa358c787d9b80000014cb32b8dac68274600000014ca3e38f9ca2bb378000001575c1aa4e35d395b80000015756012fc38781400000001574cd2fbc00000000ea400000027000000004000000015756826ae387206a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014ca97935a000000031000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006324285f50a0e379b2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a0daa7ad5482faf72511c08bdd12d7726c8beab9ad714175586ba3b9279b844a35a06daef9f114bd0c85a92a791bc18cc7443b6a1a03a9b0bd745fb82449686c9c21", + "0x02f92855058305c8518459682f008504a817c8008353ec6094b6379a14b9cbf8d7a5d98db05792c5f01326da7b80b927e4e85a6a2800000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000232000a27871234c27e497d2562f347af2cd5d11fe27624a827450c3a0d48ce6ee480000000000000000000000000000000000000000000000000000000000000003a58f62d4c6666c33faaa545751ec22f607e5cb7e000000000000000000000000000000000000000000000000000000000000000000000000000000000000011302f7fbc7fccbe10ad8c11ab4276b12e81511c0fe3e924b9182fef6190ad87c640132b9e57046bd0ff76a6399f34e205e0ed43b58d98dfab4a9ed2fd901f4ef5f054104843c4e8404f13366331aacae698e9432f75b68bcc53b8f09f761060bb900e08a0e3e2d4ed50195ed5f7b2321bbb9c0415a053b8567d62d760c83376a6a01f91a9bf3a07fbb6fb986c20a7b203b17feea887efe85436aae8d7277dded540061367e145555173824c1f408748c3cd4e9778a0e03d4ea6a61ee6c1beb114905f061ae3583fbda6aab548a9deccd3b08751edec738c4307caa72517cf17fff03f8bccd09045f5c80cb85f5f6f0a4768a30c51673404c7b4e7e6bc0855e921a066dfee8092d05a19f3018210a3ce4833eb44800cb1f7caa893bc2e080ba94b802c2c4919e9e038c034f7266fd3ca1bda0ed21a7bba4ec397716952cea88c5c80680e25643177d86ba5c9f798ff5365042ae5ae0643cd1150c6e0baa9fc354a306e2ec681be1a4642dc765f64efdc3affc7cb2a78489e9cf3ac3f808aacbb54b01335b70ac028cbc15d4289ce6648bf13e8064bfed0f69a1102b37812fb12189004c0af34275ade15c54474bf9fd009fde7c60af6b5d4316b0662b3cd49bd6d400d20cf60fc79abf9a7b6c083c4744c3528b194294a69cba4b3c19107e3f149506ed2a7958e5625486caebfd66f9ec0c3417a806b9ca78ed8ae05b017e5917a207fe4da00a2f8f173b2c731af7ac4ba51e26717f28620771a4e7b9f482d762fb05bfcb80afc2b5b6662fb73546e89ab5843847e1d22c56872cea6caee9a8296107e582a4cfc8f7eb6e828c159ce30fee5fbedefecb865cdde0135a455ae2920c031351df766df4031739cbc0d176e754dab641a71a4595f686a11197a138ef7006ec890438da08d0c7b7d86e8b5483645905eecc58298703e53dea458d17e7e3039c5d27f0bfc1d51df7705cec06ba357eab3d2a5d5c263b071c7f70ebf24c0c004cd546e8bc8c0ac91336128d98ef8d6ee96e2ac9641a750a7598439b13f79a005f88a86febaa73879e4619d608ff823340eb986b05f644cf9575617815d4bd0685082a1b899f2097cbed00dc4696b6d20fd6fb75048da52d08d12e873e723007e0d15cc81ef6ca5b351769065441ea65285e7101b5d07c678a9e85271b015e011c5112e537d7a8d497b519819512968f44084b7e01a5e86f60c6f70a03f06b0687a5774de58b7f1a0cc4483c0f5737ed55549d0d8477ed2b94f3cbe1cc4d0e002b1c56bb736cc4b5c859e8850f57bf1041f664f6c6c09afa27494ef7ced37806a665967a220b9a471191af9e63fcb9f47bc5727a865e93ac210a47acd967e7003dc0afe2c260ec7c0b7994cf8f710659d05004a63891a56483c96c505bbef803efd70fddc3fb0b3dc6b8b02fe89cad0a0309a3442dc2b58500ae731c6b3b5e049d2c19440ecf394a432fb47f5a8341937d398714a38bf4e420dc36350cb209005a5bb969c2beb2510127c79733813ae4ebf22169a1fdc509747f33b02adad901adb2dd72fcf96c707060142ebc9b55ea1f156589ddbc18079b88d306dd1881040f6736f6e45af8a4bdc56d44d770a6342766890869b6b36e280546b3534d1407a9a43b6d062a9be948707668301b837e7e3afd01c041892c258440eefd15af07261836105c73e6a7449e1a904ecf53447d556ece4686968ef4fef4c140a0ef0698c95c359536239909326b82a55089842fa60e2835f8a247d2d5d3e1c5bd4a053133d564577dd136e93f456f99a75cc4b041c24ef279d939cafcbe703268cf03ed5fd8b9367b5755fc8fc5958ccee69be6204ffd249db4348dc6b9ff48e7f604fda5adea6315651984b7e4bbe27f615195947118618470182a466212671751029c3cb273e0bc19fcb68f2ed8f222483f6f082f036f20ceaddd629c7b3a952906686281e6510342e6866a0e21b785ced459a5119b1ddc0f52d7f2717283ff32060cb45f3b283150f05758d6da5c50a6ebc0766c9c65db848f0bcc99d42bc851034a6c0eb96ce2dc4d97bfcf4c1600bc12edc7e93da080860ba4387d744b497702b5e081b90a406b8ef1ec184bdfabfd7c899b0695de99cd4756b7a9657b08c90386aa98c133fcb6f761ac7ced68899921a95e5fbc005f47fd2e7b4c2d473e5a0254171330325416d2e7ccf70fbe9c183e296af9e261e75b47e3e05517f70fef01250733046900a2239f0c20e7a874735362bb0e75d92ae93b09b12138f9ef7b0611482aafc3ad87eb0ffbf54eb9eedfa99ffad5d2a05f06c34fa8700083342a03f24466a78779993e6eb6f99271d4e65a90340278a12dde3a16f17d1f6faed405c81d60b30d27db0f38dbb7c30b5061c2ddef429706ff8a2a989fa7761b516a04eb3c5b5b535c1c4c56eea19e4a8a0074669d67aa8810b8333e1cac3c1417a200bb3077c9fa4514db4c0d43ac518e6b6750f23d6eb547118ef1b69493d4447b066f37ff1d03b04f9421e62dc19cbdf5003356b316bb0a2e8aa75e01581215ad01af9e", + "0x02f923d5058305c8528459682f008504a817c8008353ec6094b6379a14b9cbf8d7a5d98db05792c5f01326da7b80b92364e85a6a2800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000001ea003e50cc00ce3a34900219abb5440b53a8860dec5288f73023e4bfe9f8b132bb800000000000000000000000000000000000000000000000000000000000000039a0574493c9b238363e25910a96928e8e912454500000000000000000000000000000000000000000000000000000000000000000000000000000000000000ef03464c373d8de6a96585e4a6e177b1dd624e113bfe532cc080c9531ee03388ff000a5480d129f82234345116e16160be364d4ee43e28a3008032e9e0a9c7b31b033b7b07fdd6e72f85249a3a30d5aac61731cccb9f31c482f2cfd220f7b888fc04a79f6aa04714d6439bca0e4d17fa544b1ac560ac2f410943c3b67c7174e26801b3b2ea6217f20142624e356492c48d1ebb9007c77a9ea35670b7547fcad4a3068e38dcaaf1383e6581309c46f391a1e526ba53f7f983c62f89a686e60115e900da480e0637d05d437942ac4dfc86d3597ff5bab691d75a499bb86829725ff202899c4b4759d19d0a389a549239c279a7b0c14f3bf7a633061a0212a229daca06391f022b221883c387bc085f625ac638c1b7e8fbc9597b7b3f832d81bacc2a00830313a4c55e2891982653444d05412490ee00192ec9a478c6dfaa6ac8ab3c05e46b351c3df7a3afa40ed615bb6f077479b6d0f934d9f8cc3e79a6efbed3a50156bf97f4d5c49350b74195311a14c9dd76af27bc759099d136a37570d72870034353d22d120d249bbbecbc4c8ee2dea5873644755e613c764052f6df4f26b407d370ef4fa8725b097f723a43c6e7e3bd72bb603152796779395b96fa4ceb4304617efc893656511a3fd4961dddb589eaeb6ea8c4fa0a154c7838b1ed7056ef0682a27021c163608e683d55a7c3a62bf73316da6c7ea263f0fab26011c5a79304060be87a9e4378a40e09e93740e97272ef3eb3c51920c34466a588746682ab051a7565b7ca2d1b79e250dcd4ccf0a0fb5b6d5b2a77e63eff96204d0dc2a4990672e33ad069f28cc20154f2f40b0c53e37b6aa4220b1dda658afe993d62a3230095d09e0f58530734890d4cfb89d7baa345da20f7f10ba6dffdcea3adb2f7f6012d870d06e9dd46fb6d9a9a63788747ab3b5e10e845804cabd76ed8350aa2b30128a399f39f4a5699ad982d3afc8fe335b9a861c222b9f2f2ed5b77ba87775001a4f061751c5a6049371798459b70a0aea257c61ca1b167dec50760eab8806003cee6df3cd28c6339778500ae5d9b27a13325f407034fb81f83506b9345f5af07fa40764c8d883a32e90e832836fbe5071e00c17fae0c10acb74cce1d8488cd0401c92ef976d7a1538c676b96167f1b63539bf0d95e27304c167e2fe43436c002ca4366b307a2f5ea4c57c848cba94399c71bb01907dd08a697606fb53a24ef0333f4c7c7b1f28aeecd51ed230d2c4a73d71802709229aabbde51f28090c2f007cdbf1a428cf92e4894a734f64c86aa70e405c0761471090435507121dd7cab063a64295df775665fe744c84e6144d2f4aa6cd5480c84e713b2932958367e4106a7a0baad447a8fa45cf6921565d1c23474ead63170fbe3dbcfdf8e1f0e0b0b0656b9f00b89dd4efd042dfc76d534fa3590e5decd215e81d008fd36d0a4dbbf04e347c4c6076a96ae3b43060a3c0cb58af8951b2c9dfcb08a500a4e58a6d3fb048b6ed58116a2a0439381c396081903b023d1bb7f4394b0f2c1089bf1250f52037096644d3f5a0cfb180018099b68a3ea3292b1e489bf0cbf2f3dd5a0e4ce04002fc09c165095ad97a7d1493e2d18e9f7556abfc0ad12622d213d290fd3f19a05ca17603d0800178027c9dd93656930ae0cb4195dd4a459f2534cebd984306a04914377b666becb50726deb1846d788551a5164ee44d2162fe0f0d0c5eefaa9010ad9dc569c0c064d0ae362b395147ffc15d48153243ee20b62ab02b107a132075970f290b9ca121e2eff4314ac5f1b36813cb0503cf762533edd8391d7efd301ccb6b1224580856df5d02cf630fb23fcbf7270ee561ad02783fdfa1e4c27520336b6c89dd95463df5986703a9ff03e2bb935d8510f6699fccf587071a1db6204cc3378ad7c4d1f6b8893190fe47289b049dd341cbc71b5d1590674358bf500025e48a0f2e8854a8bf04b18fb8af9eea8a07f9ffb2b6bad1182e23191a233a50787641b2a3802132147769b43b2066b5b799316a1569e5d139ad1e7d664ef590669da421e552e0c378976a4878880f001e70a0ef4ab73c455999ff3ac58e8560296cf5d51264891b033ca14d65762b8682ceee30ef352fec86f3bc007b38b8c05eb3c00c7ec1e8ee422ccc42b88e73960fa66e8fb3f9b1968d327e5b2160eb803dcf6106d2f7577f91c01613450f55902e76d8842224c1288c56833916491ab071350fc9970185e67f54d2baadb3c7f2ffadc39dfa558ec336d1b771dd7da1500d16e16ca6764fe3c1f1db7367dd6b360a0a35772783cea02a05db09d1293600621f47bc63ea19ef08f79b1a8565d9ead8862ab74c8b4560d05dd7e0668a31f00105f92c89101221202b0487c8c6e5039d30e67769d4f943ffed0001703c29501acb528aba234d44c7236fed49291d46ab55bef8b345021fb86753e2d9e4a4303d182b5a793f2f858b1b03a58e98755bdde25fe67afcfce4738433fbf9fb57506713e0e9364ecd8c4705284fc79fdf75057a819b009975a06735c354f9f2e3101956c", + "0x02f91f55058305c8538459682f008504a817c8008353ec6094b6379a14b9cbf8d7a5d98db05792c5f01326da7b80b91ee4e85a6a2800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000001a2007803a5b51bf4cc540c19500ce0290ff802f97fab1767df58277b66ea3b52811000000000000000000000000000000000000000000000000000000000000000303641f067702ab9aff75c3dc0d21369f9b6863b800000000000000000000000000000000000000000000000000000000000000000000000000000000000000cb05488f333b9ad1a1b14d581996c08422ecdd2cffeadf02cd7b26f11a935dd27a06b285581b6a86dfd731a142ddc4d734b42fe3457590cd406dc53801962bc894048eaa2e6e3b1a6bd6fe1892d8229319446e67b37e0897afde8630be2df5aa5201a84338bce3abb1cd853e56346f4e55b0161c1e765412e8dd4e30501e90cbf603c3e0d344230ddd1bbb360b6c310865c81146f0d7326ba34ef3d1f3958f2ee102ac405b95bf6c11b316fb1f09fc5815eac280477f6dfbc5aae5d70d6e2db7de020dafb024c84696ef47453014fc04c9b4b49b3e37cdd154ab33ad3421d2be660064fc43c2e44db6dcd820dc07c5e3a8c9f02ad1539ff621d513166ff944e0ad012e81c02a5bb2229509112e3ff3add1a8672b377d03f4fa991dce2ac9ac85ae058e9a16af9d04fc67f6c7250193f128ef56a2539cd5ec53a86d19f7c59ac72801d98204dab0577f9c33b88eaceee5946ea5df20b89eefd3d539b1c605a826d00776c5327a04fcb553e4d98e023fa145113871af2d44605ecb7f18b6871578c602cc7f3031816b0e6dd60215aaa876028e31ece0fc2a97baddbbacacc44bdd2703d12563f0cf5cbb0a09d750423a1dac4bb839431fe5d5b943e55bcfb9f13cf105d5b776922b1945eac8fe21f4b36593557ee4153702b308baecc6afc393c2b10696c62028311d4b021b8d9e6693ff22ae1d843cbae4730727bcdf08c7e88a7c0627327c928b3aa8fb11df2487047e15977059cf50250eb87ce3635a86f251d9035379685e3b45673d4a2848be02ca134a4a7e2553729a83413d164d48b2c1f001f9e5c4d3fba67565be241170dfc791584e377a8ca8cb667ad5c49386deb02102582c793fa20eb5f4283baf9c9b56962c0e83b2d41b4addd72407daba04714c0083d7c6467b5c7c6f3b63fce75bf7dcb649014d95f4ed6e372888606fb507830432175445fc2429631248cfcec0f8e0f791b194e5cf5e2850ecef53b73ed3640108706677511e85cc86ee58f0c0049d771b37c71cd2e7e5928db40b7d1adb750784eaad6770879ffb46089bf176e29997c6cc0294101b699d358c73f2dc4f140239e8f6acbf3e7f4b1b4d9e383ea4ffc954f5f6d2b0e9ecd116894ce44d770803180a73556518f8a74e08f4f98b4c77ccdb3f6288c620ec2a4864d9396b860f02da3960a8352dda428e2fd55befd1555f11f38eac6186e2ae0f7494e24756e602342d6fb6ff3e706c735adcbff8868595ff2860ce80c64519c6c471ef0879cb02fa87bcf1167b3fe0979bba3e695a18dceab76e0218f7765fd20461fe4fee270463f60441546d2986247a2c2e2be0529345898787354b21974f6c695fe743e305b7fbd6643100e5ebbc5541d90943fad4d54a61c6d9c68a4ea30f834c0615ac018ce4986bde43ab0d94128e35e523912cf29d34022f9990f009f6aff550a10600654885b921c3851b8c2fdd7cda773c942f30db671cc391cec1ac167a40e5e301561375fc26370ec4d3e7838aecb94c85c5cdde9252ebeecf137139fae202eb01f22cc2b6c2acea46b143ee8d73b08122525d868c6a400d6b1875a4d3ecbd5b069cd909020c56c9c84904653cb3f1ade6d619617b913d99e13464fb2f15e4d10654d637dfe2f21cb7d0eccdb8539537e8ebeedd448af159a2d90011ea6023ab01e5cb78de77290be45c0ebd3af4a2f187de59cb76ea2d9ad5204da45bb549d5067da7ec6d08e94e74a5fbd5efa19e9f2b6ab057ddda5d6c61b7ac80d4cad9ec0064bd86ee90b85e530d61ff4ca57da92bbec1056a5cfb018b2ea31abbb9b55105cf237d228605876608bcc6ae6eb3417151693c06c352ccaddf66ac3645afd507a3f271aa08cd000ed88fc84c4d788b03adee5667199f85297dc948b62db6d402243ae0a0bd8bc39acb9bddbbf007a15e02127494f5781a7fca0a56f9eade86047e882a2081e8be4093cba09c70b1677a501b07753b7f1f345790f58fd26bad030196eed34309b1da84e458457e24ba09e77880bcc3e30230767e678634c46000a444572f0d9ca02c231daa732346b5a3b216ba324ba8c7264bd29d7dab049f071e7e895b95fdd920d1eba20d54fba7b43ecccfa08accf2f8034290714f5847000d5291168c069496dd2b655c893c721c0beda4cec4c374c086dcd3e61653a6018b30c54efbf11990980d259ab97a6f79d88268d0cc3377e58dff757cac7bb1038df5bc54c8435995f358c1ad961c8e940083c996b6336ae835e4e607e8628c0744a978c4e56889641d67035f8a2aba4d87ac164cca7929a5c4182d5fe6a7790293151db3f872a041022068780b5f4a6cdbc178bb9799f62a85f745791f24f504a46e564ffd22755afbd8a70b3869300c516dfbe52ee2f2a6ea98c2640164da07b31a76312745481e7a0dccbf6e641d524eac2c0f35f3970854bfa1e6ea075d070029e6803fe5570a1cf167dc49a3adaeb243443520fc6831b19935085d3158076b459b7b66dc1577545885f8eae12dc210617367f667046a34e4d876c3c6aa0573a6", + "0x02f91655058305c8548459682f008504a817c8008353ec6094b6379a14b9cbf8d7a5d98db05792c5f01326da7b80b915e4e85a6a2800000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000112002cb839645e4f926fe30710b52c66593708ab1689fab58a135a06dfbeedaaad200000000000000000000000000000000000000000000000000000000000000020ffcbcd18579d04d2130c01e3bcd529f800788880000000000000000000000000000000000000000000000000000000000000000000000000000000000000083053feac0fa855871be263f6fb61d87256280168d07a939adfc108defb1d4616e0089e260f855ec7009b8679664ac25e8c350239811a5c500f28499569f17c7bf01a694d2de48bcfc887b418763374a3d954645acbb25f1e0fc6d815b93d0994605a4eb327bbca14ae199689c025c13e58332f37f10afbb3275807b55d8f2a8c4035b858590bda079d96e669bddecc4b1da2fc0c0b13ffe8ce58981d732afbc600232817e89408bfbe6b9e2d09bf61e581e2d8a39e7f258c00ff4c05ee2cf5b5f049080d70e4fb6b08b999bdc2424c0e8ab175bbf54c58fe990629cc836c301080570f694bbe2fd849dd95442511cf9a6a30142b5bcead1ba8eec285f1d26ec1b0013d421d83f044515bf47842ec63c8063b7cf5f763c8e37384f8a8fb0bd70dd05af336a72ee4057219167f2219e725daf7f42cb57e0087438b35093adb72b8b01d54f76ac660e3d9fb8b0ede481732fb8c5474d3a92f5cbe67506ee47e7eec5052a5c3dad3e8d6e3228cbdb8e3cd1df06c323516f77eeadf6e3ec0c4ccc694b026b3626bfc1397fe447dcc9667f7f9ba988469e5a0a770559c90b5d942f9e7700cd7e955788329f94c2d3ab52104423c4de0da84ca58b4f6f851551469dde55021aaf9aca6f2744db5363c9456c5f16fcb4cbec4b4aa75884d9867d7872bc43075f8dd795a0daee0e95d5e356946253b74dcc85e183a10e8b3d24c301798b92026746068f3002975dcef4d6ee80cb60df78557a2f05f0dd00efe1f29e7d0f18043d7966b6c45a31d9d535c1110030b24875cdbf5434362a2fb1ff6a472e892b05f94b5809ce9d12bec9d40717120fcaba12d0de3e74a3fe438ee260702c8e89072157d776ee214a856f5aa796561d47d1d9ae4d9dc8bb46750a36caf3620f060462a80f00c68bf3632e2dc8efa32d2e65b8d69f27fe306e0ac2e76e1f9c496302defd3d9c41250f0470fe31a0fbbf1ebef8430240ad629b49c4f2d8a49feaf005869cfd75df412619b2aabaee8058a4966b63605b688efea0bd72c7e6fc19b70165e7e1ab4806c0051fc0092fee7a50738f60c3d38d6201139f788d02910dc5002ba05b6e865c746a0a73060b8d5752b12aee54a8a67c6ffba02ce74b295f8f072ab54ecfeacd665df85eeecf3d89b30dac1d4f326dc94fa31b567407d1e38100d173635b912737ffa028847f3d5cc162583aa25a480275da2739a2e431e23e032c870f0c25f560cfb537e12999e4627544bcf50c63fcc4f6979703005b3b27015757a6ef3a3e27174e27996b6af97fce7861cb08b1ac8bc72193a1267e13af06a3c533a72228ed4ecaf4fa70793a645bbe38df6e263b7e858e596e4ac30717072009dbb9aacca3c93a4daedcef824369795839d1b75cbc984c02ba0fc3751e01d8e50ba6ad40c2ff801892a6a82c883fd030f72c52a5512b0575ea10f2aded05cbe028b0f89962407e4608a3baab3650b392e8faed799654b0f57f89179e0704e72778f9d74685fb39ef5e7774066d3d96dbd7c470289ab5c7447b9a8ba094076097e8b285cc4ac758548e36ff0d677901d63caebdb2353f0bd8e666bbd660049af79d7e06d197d24092623cdb60f5d9ba22599c818087c1719734c75be94f3737039378be6fdd7f0cef6b5d6a98e1066860b10000000000000000000000001795050119f1139d6aa292fc26528e9accad3a46000000000000000000000000701fdf7b3605aef2fbc5db1c20f95a0e9f64ca3d000000000000000000000000ae6bb538299fb240d9b19e61f60155b87b4f587a00000000000000000000000098e05c8f4222b710d1244e6b6e6683ab60d8ef0b000000000000000000000000132a0cd86c843abec33d6e1410b94de34528e469000000000000000000000000f1e71f42fd0430564c7fb51ac7f89a3f698e5a0d0000000000000000000000004cdf2522eeab99041f8869aa128c232de91191d5000000000000000000000000fa6f5aa5cb21c7e0be328cb9f1585e99a0ef7a12000000000000000000000000c4107cb031b807deaf592827a5eae3628d0165960000000000000000000000008269e5088847196cb46930a54af083b285fb969f000000000000000000000000035f6acda8d1b2836b9914af00bc4adae844a492000000000000000000000000dab37f6b7c13653181adbeba8c3c8a1d4ad947ec000000000000000000000000090e5d93908121cda73e40741e3d0b97c4d9021800000000000000000000000032c435a64d98b2b72e092f71b613034a56f3cb05000000000000000000000000e83a7c63b0a02ffb19e9672efe793defc7b4305000000000000000000000000010201c9a9ffd00024d2a0709d441f8b06dad39ba000000000000000000000000101c7fe19424adb7d6f238845ebfb3663f15694f000000000000000000000000e6f0d0fc3e4045453e074106adca32f556a4e61300000000000000000000000048f91e8c90aaa403417c3d195c953504baf31a480000000000000000000000002704d6", + "0x02f91355058305c8558459682f008504a817c8008353ec6094b6379a14b9cbf8d7a5d98db05792c5f01326da7b80b912e4e85a6a2800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000e20018c78eab59df24e7af35b4ab3cfe1724b88f0bb0476e6d65fac04dbe18ef02c0000000000000000000000000000000000000000000000000000000000000002b15ffbf11e5bdfe43d1c5bb9d4fd2c12d86134c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b03c243c715a9ed8211eff9bd1dd8eb5c61101cc77e8d94cbd9e2787ae333b39806ca7e2454e929ea76716fc1f3271b303c6954cf318a5248593261bfbc06537d02f3b6223377c1a6ad6812af9fbc2f3c6af2df37aa3fcf2bf95d50abc6a38b7206162b3e142653b56c5d29cdca3c0fd679f80db28cbba2f2f64dd2b59427487b07fb65b5e96db45cd4e145d2e5d123547cc9474c6aa8fb6fddfc6b1030b2a8130641e6904450dcc1bb097f24246107e1545118feabc41b7ca0c930f1dd73842400ceeb4202be3f7451d65f7465518278ff0bb42a0b20dc79ee989f9ce35de66e0301713de188e21791f8f62a8202c85b5499636f620acfed8c51d2129d0f7dd507751e5b2a78679cc82f6c74a2d228e3719c19a584110d89d02c9acb754489d50446e18b0774aa72d297eabaad94930837b5dbe7e956214f6bd10a9b5f8ed24304ace049635d46ec0f4b605c9bcc12b23c76cc27168dff4db654914c1ca002f0075effa4039d4bde74ae943c91569d50875f1fbd8bd72c6c37959691f41376420092690e7607383514b836e8da58b15acc7e13f1758c66748cbd7278785ed7ea056e99098d1865b73dac7b1085ca39f22be56c2d94ab94594f1fe15c6f6097e300b5918259883e5837bc9f6eaf4c6bc0112d7c9db2b0d384f8f02442f4ea33bd01749f8f2ccd6e14dd76144a227b10cfbdabee6097873b3ac10e7e081e313bda0528fe9ec75bd4a5fafc2b09035a87bc4060c4765280825dbe60b172882048b0060a54f18b97c9155939054adba6f6c283f4a35e38a1be2fa0c0de8ad56c9511011a1c6dd687efb2057ed720d1f607758172f81a3d3b3e7a0efedeb6aba2bfd905e2b861296d5a619ec71b65a88d49509b7b9bd011809715b4302a22a4e6e5a7007a2a77fab13581bd866cb1ef5bcb92ba68da7d2b0aa462fb89a42cc863f910043ae3e76984a5a6d2fbb27c5981b0c9d682015a28f3e06b549d9004c4a16d94065ff341636d8252c6f5b55644b3337150abc849b5a3ac72c5275194b9b33142030ea78626b4a92a854d220a9241a2be98f0b5a3868363e8bea0e9c85cdd32190337a98c2095a43a1223b1dde6868dce6e3146bd96d1cebae5cafca7a7eda6b3079691a6f0a7fab3df5d99c1a91ece57ace9fb431901fbddf6e6d60d8156ee0804477cb17df80834665d8f5bc9a566c68d53bc10950f13aeee95138d10d467ac04eb56c0c88b0c2121c462dab4ac50851c9830a12fe1033c0ba051b5f4a181c600e833f11b5bf0ce7511be4363ba87f16b3dbb8fdfbac3c2aaf818590629a8f807db39b2ee6f1ecc7b952d3de9223c748366631b1dd2a10911f9a6487bea288703ce9375c1dc1687ac19cbc1823be2afe8ee29880dbd2c58ebc814d96f1cb78a035a16627975477843e9d93e47c6fbc121eb6522a2855113aee01dec687077770454a8d779bf70c0ec9d597185fa3a0f2c967acd8dfaef275de2a9a3eeb7d61905aefc2f7ec212284c5e479b78acff7e98356632a22a162b7eaddb6a6c398bb3068ba3827b9e06bf173a98e551e5f6c3c2ffe1306c4bb5ae4713bcc54d1411ab0682f85a0ba19e9120f8cd86568655c6b0312a08e4db6b250f159d3f5cfbdf32c9650bd49fed92c58f4bb2be142fc0b102bae4470000000000000000000000001fbe904f3f142a9c458f4907d7e12fa02403c211000000000000000000000000656fabd579666b3ed18529eadadf7e0c06534a7b0000000000000000000000002956e656cde6491fdccc490d7d5263a1e5146ff0000000000000000000000000ed7dd508f738cb4709a4f968717fac37f72db4f6000000000000000000000000432ab65f5fcd9e7005ae951e1c9049d14433a63700000000000000000000000099d9bced2b857f2e6755c126d6ee5eb5fee52d5a00000000000000000000000011a36db5014b8603886992f22eadfacc24c136740000000000000000000000001ef230d226086347a76261c80c06483f6b67fc73000000000000000000000000849a0ec976fb8324c7f58ae5c57fa496131c00b40000000000000000000000000a445dc9b57c3bc9263a12040336655f0967ddf7000000000000000000000000f3d3b7ff7321a4c887478c655a9bb6b5d562b144000000000000000000000000a54eeea45651acffa26f3c57fd40a98604564c990000000000000000000000009449b858ca68a343601b4fb857d1681279f34cab000000000000000000000000f87cd5344145a53db61d09b76bac6315c8c5e9fe000000000000000000000000f38d2de110c9bcdecc4b7af23c9a698476f5e37500000000000000000000000000836f22570d729d01def427cdc2f46401b152d7000000000000000000000000dbfea5a6c8a8ac8c8a7dd62c268a596c40ac6387000000000000000000000000640bdd7494ad7c60a4ff9ea7ad0087dd554aef99000000000000000000000000a5898ee36594fc6def5c71edb78065c0eaf44de1000000000000000000000000666deb", + "0x02f93ff5058305c8568459682f008504a817c8008353ec60946df799e080759604d07da4a4595128373beb5d8180b93f845578ceae0000000000000000000000000000000000000000000000000000000000187fee00000000000000000000000000000000000000000000000000000000000000a003b3c67a664f5d65b365bf2bb47efa3207dc193ab5e4316c16317dc95b964e62022e04418682abcb30d8713a920f1aca67a9526684a91c20b02c7cc50c0d9dbc080000000000001100000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001f60353fd45164ddc943332669b8d4743fce7ef1d1cf7dd820b669e98825f96997c000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000031494e43482d37000000000000000005cab5ba3db5941c6ce588b25dc6c9adb565d805629b2e4dd8e7fe6eeac303c10000000000000000000000000000000000414156452d38000000000000000000006e98c93ee9a4e7cc5c44d190f4d3dd08658428a4fdafeeca077a955ac6120d00000000000000000000000000000000004144412d36000000000000000000000590e0c79a3dde450452874a192b6f0c59a3c91b16bfe88fbb6116ee491d5b080000000000000000000000000000000000414c43582d3800000000000000000007acd949642dafa291ed327e123b50cf0dda9fc7a16fc655394e40b6c5f73e330000000000000000000000000000000000414c474f2d36000000000000000000053ffd8fca658ef8a853379eaf490ef3ade15f183a4fc816bab2edd083d182960000000000000000000000000000000000414c5048412d3500000000000000000652fa7c13c1696f321ef246dd4308a122ada7e7c0b04a6159e19e77fefd5a1f00000000000000000000000000000000004150452d370000000000000000000000181cb4081b256dbb6b067ef6668b8ff93d51493a4a738cb464ef02209e9484000000000000000000000000000000000041522d3700000000000000000000000031909be371a6eb458fa5971c19a496efc30ccc069b415abd23a986087aae36000000000000000000000000000000000041544f4d2d37000000000000000000004bd17f89c4545f80ca5f5138deaf412df9e1ed240bb16532ca7ca63496022f0000000000000000000000000000000000415641582d3700000000000000000005af1ade8046fb4cdd050494861b140fcc6d1966bfef56f8c050005e05b34cf600000000000000000000000000000000004158532d370000000000000000000000dc0f4ffbfd73f75013e59ea8197012db4de5f2c2dbb445bec1b8110a91ff63000000000000000000000000000000000042414c2d370000000000000000000002df2bc73e267940de23663550ae40e2ab04829cae6b3bf1ea47c7f3da449c8f00000000000000000000000000000000004241542d350000000000000000000004699da57bd2cad90fffbcd450dbc551b03a1d0659c2a18e967cd3ad5bbb148a00000000000000000000000000000000004243482d380000000000000000000007162a67b6de914bc616e250087be4f4b32f1091173a9715ed529bf49fadc32f0000000000000000000000000000000000424e422d3800000000000000000000046d4c5002da65edf23fc3f276ae8faed3b12bb5152a628a504217dc14e206170000000000000000000000000000000000424e542d3600000000000000000000012307627fd75b93d85a5bf1b131c3f04fe06e2dd1d42e0f69ded501d0b2383b00000000000000000000000000000000004254432d3130000000000000000000032d88804c27889bc102b55175e470c702c5271d4f47ee65609be48cd12ce92b000000000000000000000000000000000043454c4f2d36000000000000000000071925580daa4d3f23f23a8d6eadb8433d4d97f2d8a951fafd467e6ef58805e70000000000000000000000000000000000434f4d502d38000000000000000000063d090b8ae4062273bd544a98a30a8ee7be7884ce7cdc8ca4c76126cd19f4e400000000000000000000000000000000004352562d360000000000000000000007bfbb5c5cb2a8fd2315b19610cbadc839675cff0d07d90bbb38df585ad4a9910000000000000000000000000000000000444f444f2d3600000000000000000007872ede04c06042cdde553e4786f0190d1c0fda22c7122aafdc72786fa8565f0000000000000000000000000000000000444f47452d350000000000000000000566ed4ec703e17aef519a33b94b4b3f68539c78eed4f379a60214956c1f64360000000000000000000000000000000000444f542d370000000000000000000005ff2995ee5ead55d78716aeccd62bea78617c17ddfe3804f75e7a392e43a73c00000000000000000000000000000000004450492d38000000000000000000000627ea347822b38617158da472ba9e0d9ddc72ba373687e9721fbf5b5ebbc3810000000000000000000000000000000000454e4a2d3600000000000000000000010ff91bca840bcbd139cb2b00460f43f7a05c6cc5055ecd935d6a5693e29fd50000000000000000000000000000000000454e532d3700000000000000000000079ea2b418225dc558746a181f974c3f6148d586d53e776f1d050560ddabf0780000000000000000000000000000000000454f532d360000000000000000000006333c241da9571347aa61fd8e17504222087149377c2bebd4d9e985b4627ef6000000", + "0x02f92af5058305c8578459682f008504a817c8008353ec60946df799e080759604d07da4a4595128373beb5d8180b92a845578ceae00000000000000000000000000000000000000000000000000000000001881e400000000000000000000000000000000000000000000000000000000000000a003b3c67a664f5d65b365bf2bb47efa3207dc193ab5e4316c16317dc95b964e62022e04418682abcb30d8713a920f1aca67a9526684a91c20b02c7cc50c0d9dbc0800000000000011000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000014e00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000031494e43482d3700000000000000000000000000000000000000000000000000000000000000008000000000c7921b0000000000000000000000000000000000414156452d380000000000000000000000000000000000000000000000000000000000000000008000000001f3964f00000000000000000000000000000000004144412d36000000000000000000000000000000000000000000000000000000000000000000008000000004def5cc0000000000000000000000000000000000414c474f2d360000000000000000000000000000000000000000000000000000000000000000007ffffffffdbee8bf000000000000000000000000000000000041544f4d2d370000000000000000000000000000000000000000000000000000000000000000007ffffffff3b2fc8e0000000000000000000000000000000000415641582d370000000000000000000000000000000000000000000000000000000000000000007fffffffc6a6cf8d00000000000000000000000000000000004243482d3800000000000000000000000000000000000000000000000000000000000000000000800000000b94e91300000000000000000000000000000000004254432d313000000000000000000000000000000000000000000000000000000000000000000080000000226e1016000000000000000000000000000000000043454c4f2d360000000000000000000000000000000000000000000000000000000000000000007ffffffffde633a60000000000000000000000000000000000434f4d502d380000000000000000000000000000000000000000000000000000000000000000007ffffffffaec779900000000000000000000000000000000004352562d36000000000000000000000000000000000000000000000000000000000000000000007fffffffeba506c30000000000000000000000000000000000444f47452d350000000000000000000000000000000000000000000000000000000000000000007fffffffe750e93d0000000000000000000000000000000000444f542d37000000000000000000000000000000000000000000000000000000000000000000008000000004ba7e4d0000000000000000000000000000000000454e4a2d36000000000000000000000000000000000000000000000000000000000000000000007ffffffff488523d0000000000000000000000000000000000454f532d36000000000000000000000000000000000000000000000000000000000000000000007ffffffff68f0ef900000000000000000000000000000000004554432d37000000000000000000000000000000000000000000000000000000000000000000008000000003ca5b9200000000000000000000000000000000004554482d39000000000000000000000000000000000000000000000000000000000000000000008000000013057cc4000000000000000000000000000000000046494c2d3700000000000000000000000000000000000000000000000000000000000000000000800000000a54a0ae00000000000000000000000000000000004943502d37000000000000000000000000000000000000000000000000000000000000000000007ffffffff28bc5a500000000000000000000000000000000004c494e4b2d370000000000000000000000000000000000000000000000000000000000000000008000000006f1808900000000000000000000000000000000004c54432d38000000000000000000000000000000000000000000000000000000000000000000007ffffffff878330f00000000000000000000000000000000004c554e412d36000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000004d415449432d3600000000000000000000000000000000000000000000000000000000000000007fffffffec6e3be400000000000000000000000000000000004d4b522d3900000000000000000000000000000000000000000000000000000000000000000000800000000cae2fe700000000000000000000000000000000004e4541522d36000000000000000000000000000000000000000000000000000000000000000000800000001f44b582000000000000000000000000000000000052554e452d3600000000000000000000000000000000000000000000000000000000000000000080000000033af20f0000000000000000000000000000000000534e582d37000000000000000000000000000000000000000000000000000000000000000000007ffffffffb30f34d000000", + "0x02f93575058305c8588459682f008504a817c8008353ec6094223edee99c943783a59d0b6e98302b7bd4a6cc3880b935049b3b76cc00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000002f8000000000000000000000000000000000000000000000000000000000000030a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000168686da01a91349036eb9a64aa36075c2fb88d509c000000000000000000000000523f56158e4b5123eacfd0fd0521c9c8a8e3f308000000000000000000000000dcb80c324342dbac314e0d6d70ed25b575789e27000000000000000000000000032371cc2059e4bec142d2b02a25193c571c0f4cf5ccc77fcd5fc208f25af69400e1a4c5836e206d181a0d1d101a774f987f8b7b9afcf2e327ea91fac3e04286061a36f169223983c58f4680c1d72524ed9d540d653caaafcd983dace71a6dd30267e5f5a5fd9cb461ae4182e3faef5e9d6086bb6890650051e91e7bc85bf1b2032c44884a2a49afdbddbc726322423bfb99deb89501733c752413f4a5ae50c906e8c434b1627ec01166ef37bd76c9a1c5df2a91a25ef319be312a3f8e5c4f6206b5ca90e586e0efd8b6e74913711e52dc9226bacadae4964018dc156e75878400eb8506f8e1338b5c543c3fa06ee1d4e86fe64781c3bbc857acc99cb1bdbbb9031e53126ce9f73ccae2f4115676df4d9369c2e93694046bf0ae2343b9d325b7015be3f49dd1fb6f970eaf96520a925f433cb67b9f59bb6ff6f1b3ce205c745501fe7315d4446c9fe0160fac314f07d7ac308d9f7802a33e31021fe10bc6463b06747b446cc3a7cda88193befe4f4cf1d6485505f05ebb84dce4020f8b9e06f0009a2552f0bcd4d73dcdb0d85735a66c302997f3842d421bc706ad620115e3db065ad74d8d9d2a4598a65b537de2d5bceb653bf06bf753af2a27f0b32263de0f0318adfbe9c1485e648f5968701fd775431eaecb53feda886e9b4bef6e5e13a603f42af3a3a203f4e93160c2fa248230aeb653309d5b30fc0ed18a355621bf1307257a723b1576c1ba6d5e1996dac83a903a6d609356cc0f617422dfb0bd753a03f5acea77508ab050656494a26312df4c9c025e881f53e42cead31ee47a9f2802bf073a9d123a1df1995fd380a897d80fcac31f9ed89fbe3937b0e41d5c63b903671de9822bbdb7bc0f0fba88fd1007f9ea94c96ba50114c42214bfb885ff4b078e077f9b83ee2df24920169a8b70c7385e10c61066b9925260761fa989ebdd01fdffd3da05149394a7ea02f6144921251dfd0a9e82bde5679249f85f48af0707f04aec2963d8b5ee64423eb52ef9aec3c39a1180be4b2ec78902b023b0537801ffd71e3bc468059a7a3fb26d1e26c5085ddcbecc21e01b81864e470ff4e0a406a767c7e4525a082af2d22066bbb5abf6300d991dcc9c4413af2aad1756d830019e3a5c639465f2c34e895e4062f1c6a58371248152cd02bade7c542116e889003033970d0cf8a9100ca06e989820299dedef2e408cbfaa4bb4064c5c1a568c04c468268382b55be26237c06ab7c57aa66ad50ab6e00d21c94a8a0ea366172e02ae63eff3c2110db4106296f47368ac0ef5dbf21b410547ed92bafa4c0772940305f4a6df3d51e2b9725b2a542ec41d4e4ccb716cd5e04bd31e65b3b65d386200d8f20b8892098af2667c064199edb08e557fe6451b28eef5e59d50b45ae01b0586384f7cdac8b60d7e46ed39656ca048f7a1c00fa3b3844e0aebf851db611503094f96372deab71598635e27c76f7400984dd9ee8f70921aadb40ea6e3ecd10553cb7cf6061143d3009c8b141b9af86dfb241608e737b4f3446eabb37cb71502e3039c07d0e51efba1902275e89e9aad04b9b71fa271f86bf88a86da08a3c3063c74be6920659fb280bd6dcc3af5bdb5d04125a65a36914b95dd09de4a0aef046a98a11c636ca9e2281790c9a90a142a1ee18b29f8f515780e354fded499f70611b52ac102ed92c96147daf2de5acd8ac018c02040188fe08ee975e707332904f4aeee894143f587fa434cc1a5bb94e65b8b9630eac6bcce03980ebf72b5a702dd07", + "0x02f94055058305c8598459682f008504a817c8008353ec6094fe76edf35648cc733d57200646cb1dc63d05462f80b93fe4538f940600000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000003f6000000000000000000000000000000000000000000000000000000000000001f80353fd45164ddc943332669b8d4743fce7ef1d1cf7dd820b669e98825f96997c000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000031494e43482d37000000000000000005cab5ba3db5941c6ce588b25dc6c9adb565d805629b2e4dd8e7fe6eeac303c10000000000000000000000000000000000414156452d38000000000000000000006e98c93ee9a4e7cc5c44d190f4d3dd08658428a4fdafeeca077a955ac6120d00000000000000000000000000000000004144412d36000000000000000000000590e0c79a3dde450452874a192b6f0c59a3c91b16bfe88fbb6116ee491d5b080000000000000000000000000000000000414c43582d3800000000000000000007acd949642dafa291ed327e123b50cf0dda9fc7a16fc655394e40b6c5f73e330000000000000000000000000000000000414c474f2d36000000000000000000053ffd8fca658ef8a853379eaf490ef3ade15f183a4fc816bab2edd083d182960000000000000000000000000000000000414c5048412d3500000000000000000652fa7c13c1696f321ef246dd4308a122ada7e7c0b04a6159e19e77fefd5a1f00000000000000000000000000000000004150452d370000000000000000000000181cb4081b256dbb6b067ef6668b8ff93d51493a4a738cb464ef02209e9484000000000000000000000000000000000041522d3700000000000000000000000031909be371a6eb458fa5971c19a496efc30ccc069b415abd23a986087aae36000000000000000000000000000000000041544f4d2d37000000000000000000004bd17f89c4545f80ca5f5138deaf412df9e1ed240bb16532ca7ca63496022f0000000000000000000000000000000000415641582d3700000000000000000005af1ade8046fb4cdd050494861b140fcc6d1966bfef56f8c050005e05b34cf600000000000000000000000000000000004158532d370000000000000000000000dc0f4ffbfd73f75013e59ea8197012db4de5f2c2dbb445bec1b8110a91ff63000000000000000000000000000000000042414c2d370000000000000000000002df2bc73e267940de23663550ae40e2ab04829cae6b3bf1ea47c7f3da449c8f00000000000000000000000000000000004241542d350000000000000000000004699da57bd2cad90fffbcd450dbc551b03a1d0659c2a18e967cd3ad5bbb148a00000000000000000000000000000000004243482d380000000000000000000007162a67b6de914bc616e250087be4f4b32f1091173a9715ed529bf49fadc32f0000000000000000000000000000000000424e422d3800000000000000000000046d4c5002da65edf23fc3f276ae8faed3b12bb5152a628a504217dc14e206170000000000000000000000000000000000424e542d3600000000000000000000012307627fd75b93d85a5bf1b131c3f04fe06e2dd1d42e0f69ded501d0b2383b00000000000000000000000000000000004254432d3130000000000000000000032d88804c27889bc102b55175e470c702c5271d4f47ee65609be48cd12ce92b000000000000000000000000000000000043454c4f2d36000000000000000000071925580daa4d3f23f23a8d6eadb8433d4d97f2d8a951fafd467e6ef58805e70000000000000000000000000000000000434f4d502d38000000000000000000063d090b8ae4062273bd544a98a30a8ee7be7884ce7cdc8ca4c76126cd19f4e400000000000000000000000000000000004352562d360000000000000000000007bfbb5c5cb2a8fd2315b19610cbadc839675cff0d07d90bbb38df585ad4a9910000000000000000000000000000000000444f444f2d3600000000000000000007872ede04c06042cdde553e4786f0190d1c0fda22c7122aafdc72786fa8565f0000000000000000000000000000000000444f47452d350000000000000000000566ed4ec703e17aef519a33b94b4b3f68539c78eed4f379a60214956c1f64360000000000000000000000000000000000444f542d370000000000000000000005ff2995ee5ead55d78716aeccd62bea78617c17ddfe3804f75e7a392e43a73c00000000000000000000000000000000004450492d38000000000000000000000627ea347822b38617158da472ba9e0d9ddc72ba373687e9721fbf5b5ebbc3810000000000000000000000000000000000454e4a2d3600000000000000000000010ff91bca840bcbd139cb2b00460f43f7a05c6cc5055ecd935d6a5693e29fd50000000000000000000000000000000000454e532d3700000000000000000000079ea2b418225dc558746a181f974c3f6148d586d53e776f1d050560ddabf0780000000000000000000000000000000000454f532d360000000000000000000006333c241da9571347aa61fd8e17504222087149377c2bebd4d9e985b4627ef600000000000000000000000000000000004554432d370000000000000000000006b126954fdfc445cc6c1b5cc993fa024f97413c4c5a4efaad6dcc5f35facc8000000000000000000000000000000000004554482d390000000000000000000004396e", + "0x02f92af5058305c85a8459682f008504a817c8008353ec60947a7f6d1512ca406cb132e52fe8d38a3ad7c14fcb80b92a843fe317a600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000002760000000000000000000000000000000000000000000000000000000000000001eb7d68efc02a2140e273c053275c0687f3e196fba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000136b19af520bdb27e7e997027c8f3e0bfc12d639943000000000000000000000000645313695b2e971255c86806c9d9bacc97f7dacb000000000000000000000000d3ac49826b956c8383bf5eb598880a49932727f2000000000000000000000000d8c4c7e908cb1a64b21d32c51cfd773e4b6e11af0000000000000000000000007b3829c74146416ac818d393ea62a0bc86130370000000000000000000000000a60d378d832a447379d7bef0d8acc1a4ea9c4912000000000000000000000000b46a4f461bea202d7599afec54f9d4ccbabfbcec0000000000000000000000006ddb93e67f6b4ce03f1f387d6781ef657ff8bcc00000000000000000000000005c680682d111a7cd34c16318da75b35422bcbdf600000000000000000000000082dd7de67b395b955a162bbef760345f8912eb6c000000000000000000000000cf9fc5ae47c1cd191b1a7a18dc9e0be2301bad430000000000000000000000004c769ffe431119d5eaeb8d0215cf3cef02546516000000000000000000000000274f8689df5179f77a4424fbfa6f34e52184325a000000000000000000000000ac1e0202c9db91f6716b5316951dcd4a481ae587000000000000000000000000052a778b0eb7b04ee839731e081ec4f4e72077bd000000000000000000000000792a108065f17e09d526637d19c6d47e3237cc0f0000000000000000000000005aef695f2f64f2e9b0ff02fa7261c2adae7f7c69000000000000000000000000a53cd9f85c6583948f93a4fff9e4a2d0fae4bd9d000000000000000000000000b024db6d253bb1182f2178d4d81c6f16d8c2287d0000000000000000000000002a2c9b0b33c502ff1972e5c55cbcd695348e37d0000000000000000000000000e6105398b6293b9eb45dfff7fbdde63188a93981000000000000000000000000ed63c3d2cd1ef0fdd747127de25cd545c0def7ff0000000000000000000000002762384f5603366551a811022f786d32bbd7f4900000000000000000000000004d643900ba5a0e13b7f802cd1f04cf7ac4522156000000000000000000000000e7e7b2cb7a38fb07b1da63e1398b99eeaa6aa028000000000000000000000000b86f8f5f17ae5fceea279dab490f90573470bc61000000000000000000000000982734b05239b49ecec796d774df61a1864d608600000000000000000000000055f6d9301886e91129bf5e576fb678c0ca96b3d800000000000000000000000076586cb17dc63510e7c35b971f917f4be7f5c75c0000000000000000000000003654f65ddf4ea6817d1de5749350b54ef503630f000000000000000000000000969106e29ca905254e861f6df03c0377d07f26710000000000000000000000000bf4a6b5c04220159bf4a597862157629135d3c500000000000000000000000030b330f08c494ccf4fe6e32638634e116e33e38d000000000000000000000000c1a33161a03108f04bfd51ee9d77dcd68a1b8f46000000000000000000000000d4fd17890aefe1f8169440b8f78a31d65ffd2432000000000000000000000000b86197fa1d82f4b6426f0e7b44d9563983bdeebf0000000000000000000000009a68a21892ba70d2ed6806a651680a0e610d1977000000000000000000000000784ac3c918cc7d2f994f0d792d63303c4de64e3f000000000000000000000000ba8e7421d29ab1c675283dfea3a352d62ae5886e00000000000000000000000097d5f3e91c08a4d3e3f0831692f0b20b9ec032190000000000000000000000009f4f3be11ebe14ecbdcb85fe34ddabc2c1051c6a0000000000000000000000001601b381488b45a12a24a3bb750a7908fe610045000000000000000000000000f9a7200b6d7daf5a5e30f63e5fc3e912b1a2fdea00000000000000000000000077e0536e0dfacf7bf305157bb2ba2711d12ad7b50000000000000000000000004a127fcfd18f2d6d87a216a94c8f6d737b617ec0000000000000000000000000dea972b375b866f1ca680abdf9fbb8fc1a5338da00000000000000000000000047318794599801babafec5aff290e864592101130000000000000000000000006097a263f61dfed20eaedde9cbf9b1bf35a1c4c70000000000000000000000002bd7f29d10e92fdcdeea6c8dc18e3d659e9bd923000000000000000000000000a0826c3c53bce48474cd90816de26784c7dd9497000000000000000000000000248176ed4f9e21a20950eb012fec09ed1c63eb070000000000000000000000009c1ebc0beaa91cd7c541dabcbcb068d335df91c100000000000000000000000033dc979771f368e2da9254c323b7b33806d9baf2000000000000000000000000f6864df3c201dccb89c9c753a19eb73e75ac9082000000000000000000000000c491242175483a9b7ccfd3b98c90700d7fa56ba4000000000000000000000000731c3c41451b1c9c66adb76801e4fb384660e16f0000000000000000000000001eb72a243c38ce58f17a320295f751a0606c94fd000000000000000000000000ba1d73", + "0x02f92af5058305c85b8459682f008504a817c8008353ec60947a7f6d1512ca406cb132e52fe8d38a3ad7c14fcb80b92a843fe317a600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000002760000000000000000000000000000000000000000000000000000000000000001e1cd5026339e94719ecea3e5dda7eb7c7abbf110c000000000000000000000000000000000000000000000000000000000000000000000000000000000000013603f15985493b726bc6fb6b9235e302334f8128e28db5926c0a00a645662eeb2500acb02c24ea0e10ee1100fede5a824f46fa9c34172148ec6a754d57b6b0b3590267b4242a411df735deeeac9480d3796ceaa6445c3c2932b124c63c44dbc1ce0619a17cb6f94d81edea1d05c3ad618cffa473a5be78776cb5ab5235367506cf05b792da9608f9bb98b7b8d641cb6211df26d68ac72fd0277941f1e530eea5d805170d30df77f3eee4020f3b5ebee82e1938dac64783a2c2ac6aec0d2186716a07e7237b65cc5ba5440d9d707fac679ce5f03780dcf980b779c2c7debfbae461055045c587550d734c2f8084c4cd2ff81c9fdcfa7a5bb6738119832e233795ed04c23eb90a6a8d6a82adc6b8e943ea55049d56ddf990eb02d7ac10ae3fdbdf84035ae4fd5396027f096346d5e85ebc65f5a1f72ee81457b87461aeecaa6a523607260afa417c90d8bdc2256892ccb104413e5e1c65a3030421fbe3d3d0953186032827ff3a8c2cb3dbaad31f089de2283b0bd04e8dfe0cfc02405ecb413d2dc0b7ed14bb0d0020dc0c2192c69ec84e8b2895333800000000000000000000000072af07c3cedd321a964a181d0c55d983458d805c00000000000000000000000058a10bac1df6bfacdaa890c22705a53ab805172300000000000000000000000071c2c083cac14ebbe1760149095be60d9c127a50000000000000000000000000a1f9e069ad0d6494ceab4e82ffee0e56325aa438000000000000000000000000447010b782c052d29a08e3bf811677b72828b0ee0000000000000000000000006143ca8081dbd00de74eafc3df334542651b7f510000000000000000000000001828be8542e16cffdaad1de9b0d4fe1950a0550000000000000000000000000053a6418aec94ef4a5ae8dbff2653fdcd23629950000000000000000000000000401895e6188a7c6e2c1df8c3028aa12809a9f736000000000000000000000000e18e0ab827aeb590a1f93a86387cb1ea8630ff2a000000000000000000000000a21181669d0a269b4007c30140e57774808aac91000000000000000000000000b31708a4030bbf7ae74da5a214b8d2f365ace8f100000000000000000000000022e37a6e3e361879793e79420cba8112795006130000000000000000000000001ae9517c3190a3d0141eb3dfa1c20f6f977a4b0b0000000000000000000000001c6077ff61469ea4e65e6b15b887e831b9c97ce3000000000000000000000000e2094fb872833e2462ed726c1cd08d5da2bbb88400000000000000000000000024fb922fdbce46e246de2ac644aa2247aeae3f7d0000000000000000000000002ac5730e3db26ed489fc718fd9192d236c01d113000000000000000000000000f6c7fdbb82dba1b5a73c3f08f3974bdba799053700000000000000000000000072386d60e149c46193dc3680b986c45dc997b7380000000000000000000000009ec69396df6d09c1836118b43cff303003c0a3d7000000000000000000000000b66f2b7bf657c7cedc054f7ccd70c343040a7a27000000000000000000000000f2d62a5c4b802535429db4f51cf721ac7f2cbe5b0000000000000000000000004464b96279aa9c9fbbb40a123c4e7baeae104c960000000000000000000000002b1e1ee908de7c7388980860d2e319e1364673a0000000000000000000000000cf44a34918d5c4f427ea13f587e60399e9582aa50000000000000000000000006b6e1fe53da79ad5b190648734ec8a54e6172b9100000000000000000000000072fa3426821c21d690ffe1a0ecb698e3c4e096cd000000000000000000000000f149a4bf25313c749ffa6fbc9cd007084f6b60c4000000000000000000000000bacd652e7204d5e6ebc53287eba0741014fb8f6c000000000000000000000000cee7f7e704132866fdaebd4c0c4f223da5bd96c5000000000000000000000000dcde6a784dc8f4d6958e166e104d990155b993590000000000000000000000005ea7cb70a003d4626ff0a91fa2a143107a1370840000000000000000000000005fbbdab6f0172b7fe346ebf6054691eb21c67405000000000000000000000000e84c9dfebf04c6a7623fc789ed34581d26b3086b000000000000000000000000ca29863a35849bc6ecaf3d65b21b87e3c68b3ee3000000000000000000000000412345bf1b0682852e2537cb3b659f01d8d689210000000000000000000000007a6821cf3a25c58204e6791289f50c8edd44482d00000000000000000000000026418edd2bafeb0f5ddb785ad97d610e75c819d6000000000000000000000000e5ce4bfccb2134a07f30bb41e69deeb9e3c8bb220000000000000000000000004cd8b41de1aa2a8615f1a0ca5909bc57ff33d5f70000000000000000000000006143224bc5132d1a2aea9eca08873baa9abb5b620000000000000000000000000514171d8c7c4f70ef7ab40a0f0cfe46bad563490000000000000000000000009ed09743921dd9773b72bed9b9692490f3ab15bb000000000000000000000000c84d71", + "0x02f92af5058305c85c8459682f008504a817c8008353ec60947a7f6d1512ca406cb132e52fe8d38a3ad7c14fcb80b92a843fe317a600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000002760000000000000000000000000000000000000000000000000000000000000001e0cb95d9fead5e9dacc4d4898956e3d7062baae97000000000000000000000000000000000000000000000000000000000000000000000000000000000000013612bb3690f781782693f24df908bca67814c3f85c000000000000000000000000ffbcea269917c9b61acd951cca931d7dd2963d300000000000000000000000003b79aa0645d97d1f508cae8bbc3b919653e57ae300000000000000000000000071b9a212abc156a0f32c34025cb1b4cab81cab80000000000000000000000000a7146be486deab1379b193b34e131b34731047270000000000000000000000002e24f24dd384d80f0ecf85c08278bf076aeba6cf000000000000000000000000169bf9277fdd84e3c3f886bf0075942a5792b9a10000000000000000000000007c9776bbe841a1ad24855d53d1e3f284d4468c9c0000000000000000000000008c96dc8321f7b7f98fa09dd15d8dbeb645a3edee0000000000000000000000004c8bbf92a27aa299aa9160b112b72b551dc9bf350000000000000000000000000aeb865d36e43beed953d26c58169ea1c4cbb1b0000000000000000000000000c59245ea1b0424f4e7d7cba92f7c0ef746e0ff9f0000000000000000000000006bf3c3e065f480407dbda50db4b93c146b6bcf9000000000000000000000000013b74951662654446b62326d6b0997ee0221435d0000000000000000000000008aedb8c10bc5b05ec961a139fa0304e067bea5550000000000000000000000004faca2a8d3d81482cf51885cb3afae5477fb2a420000000000000000000000006466ee2e9e9c17f76db754b5f21f0e79c71567330000000000000000000000003a772454c58bb5a73a5078ce7ddf69efa19af5ab000000000000000000000000d6f8ed30b54cffb7cf91de33ca5bbd8b585a7a1c0000000000000000000000004a02f7b782e4fd7ae50f8c48cbdb985aa3088b0b00000000000000000000000043aa712e06c66a62cc9816ee0ee658fbeb50b96000000000000000000000000023158dc5adea2787c9b1248d4ee480c900adc0090000000000000000000000003e11ed0813839198ee3ba1d3366433146d862c7e0000000000000000000000001ded22c0642a88c0f566f7f64345b6d988ffa3c1000000000000000000000000e8348cae9bf1a470cd98988710849faaf261d2560000000000000000000000005df75f3b0f8ba6e496a2f96e266ad9e0e3eb0ae400000000000000000000000008defaf0ade552c9e87711b448071b07c051bf3d000000000000000000000000738dc7a068519172fba1ec750d59fd3f433611810000000000000000000000002076081d1cda092ff7492760912e5841398b9d370000000000000000000000001f96c8767a3a082587548244f4fab67904ddd2b300000000000000000000000053484761d279f86ce167994fd886dc264fd9dc680000000000000000000000009095c6492f6ef9120dfad7f1c081958203d9cf4f0000000000000000000000005a23653cb3a44ca4f056e4722b5fe0c0575cfc72000000000000000000000000ab7fbf32862a932cdb28b8bc0824f1b4546d1976000000000000000000000000bc4817f28699d928e9490dac2a494f11ecea5ba30000000000000000000000005171521538bb3c73aa5066c3bac7f969faec3573000000000000000000000000c1410ca1ea6f53b8fab97cffc2bc0f93c4a4439d0000000000000000000000000401b26feed11e5a1acf1840c91923bc8564afff000000000000000000000000a68aaf58ac97dfed3d4bfa32295e7b5efafea6ca000000000000000000000000f25473f83a28fe7e7cc70e70173051ce0e62663e000000000000000000000000daf9e0081af0af2369eed1d49818c6da2b9ba180000000000000000000000000914fb98ecf0788c902edc8fb73cb34847ec9d87c000000000000000000000000343b492f581cca47889080f60f5c988bcec92e6d000000000000000000000000414230eb2f84649b46b9a493aeaf1561cc25e30c00000000000000000000000092b70ec4ab3ef53eed56b2fe7204e7447e375905000000000000000000000000a740a2a83a3fa4ba2babcabda0ec6ee974ded71f000000000000000000000000313777654ad6856736b6e85c8814fb3479641c510000000000000000000000001471e12e619caa79bf3bfb4326541d36e579bf30000000000000000000000000c2e13cecabd3df8f2ae522f5e2694efe0c00720100000000000000000000000066ae5753f7222247f8650ca0cd8c5fd52467c72d000000000000000000000000667affa88b2e9785205fd4f354b90a895805b1d90000000000000000000000000f5aefc0c5cbaf408b80c4ca954fd7670601ba020000000000000000000000000d5725723049bcf05abfff6188964a66bdd6b4600000000000000000000000005c689c1556c575526f156084c3af54b3d1070aac000000000000000000000000caceda5eb6b5ce8056a67f88770b240c0365c59e000000000000000000000000c953b9fe172587bf556197f18dcc0b9e02d1f25100000000000000000000000050045c4f7a73be883391b9c9bdec57254aadbd66000000000000000000000000c9952b", + "0x02f932b5058305c85d8459682f008504a817c8008353ec6094b6379a14b9cbf8d7a5d98db05792c5f01326da7b80b93244e85a6a2800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000002d8006460763db9ac72c2f2b50fdace40ce639a8a5a7a8f3448d0ef0222f13552e1800000000000000000000000000000000000000000000000000000000000000039986e1abf0e85466243ebf41c6ebd6742dd202eb000000000000000000000000000000000000000000000000000000000000000000000000000000000000016601a379b7faae52bd5d99f8215c4daf532459da7d44827775d7df34544b6f4f96051e0b8b80b8119ed29bc8cd6e581b65181041dc29bc3ef3d64b4dda19ccfaa603a2d65e441d338af9ae5fa08d8de3b84e812710db8cd73f8818a9e019d7cf3003a53f00c37f0577262aa9bcdd6c0f0be55dacdbb396c181a8a627536989a069019409c4f7100fb2ecc690a5e0fc498ac45e3f189eb79c9c545ffe07083dbaff02f3d3ea3ef6e8b93f7858bbcf22d2f0418de3f62aecbc3f494a38d1d692924705ea42b84542a37c0dddca63c8a88522c5ff567b1970d006a26c098c3c1bd4f307f213f3e9449f720059484b2158e18fc3dc6725964b29554c23e13c0ba71e9c05f1b5ec75ab67620dd9fb0e78933a20fa8f13bf2ce0b0ddfde58888a7320bca06ebbc67ff22d63706a24c2f682716a7d5c67c153a256242b0584765899ed01202ccb21da783f451488e79930235cf21211bdf4ada182f97b11f933adf1417b107676e141554969419964298389d5e37fd07ba2215b6e6bc2de71c54e0dce5ca041abd3e326827bfb89065b494704a96aec5b500de3bff205ac71ba3d2fc7ccc002b6984c53a0d19573242eb8ffcdce31efd9e086e047f5fada39cf5e9ada1940116e464b0ebdfc16d86c34703b003f19f87ee2c5cce0d6bfd91766fe0e50d650164ece0a91790d69a88d69c66dc26c41da9800446e76ecf8cf7c12f78201c7407c191f592da1f91eceb5731423eaa7b5dafd69d7a68a302629e6b6836bf3d07029374cd2d202d7e6c068ba2c11160db86781958252f176f36b9073288c9a70200146fe5b9ab9cb7c85902c79a5aab8cc627c3ce95293d0f9317bac108f43b2403c15d5cc60bc572079f83aee1236c97baee5a84eed623bab93da9d667b75d5f00ff0e48cc2b6de0464ced2a17a32f8fe47d6387b3eb929dc33b7bed335869d602f1d09dd5b907a63f7ae972fef3204136b963f4c84c9e85bc303461cd21798a0771f5f46e1cc99818ec3df8e949dd01b22ffc195999ac6aec96c4cfbb0dd7c803318c49d79fd9ac92f171243989372d947816693a9f80a44907c6ec0a5c1b7c07b2b2118c482e220a44489009bcd8b8dcea5dc3518b052d43d5f1050679ccf403162b2e1d7f91fdc216da72b08c6c3a866761d1e12b0bc3fbf3d8e47949c4900441a58b0580eddeb6fe0331511a637549c2aa930d3c27f04d515111a54501db06b4b538bd307ae3cce6377f552272d4c30265e039486b106230dc6f1cc6f15b00a3811123a29975ad046357b4488d5754b5e0bedb8c4569e6fc6f31368ee4f2044bce11791bc5872d938c1868e8768edc73f839690bf3e66b568ccff46f63c107b80829904390ee6ebb054e0d3057779f11bd1ed1dbff08e513ffcd7ca8f742032419cc994c42367efe45c2b42d6cc4c3391231fed50c02c42d957414f5d16700f7e63f52294825d5f22c53f8463ab74d1204cce19c8de1e4669326ee1fd8fd0169fb72a1f89e4e412f57d0aa2482a56e426cc42a0463f525292a4b9423c50807232c80aaa587251e505f30b703990b84a9acf0237f56707a0a89b740826d1205482b322e3515aae609f5885285689efa94d5237293c6faa760e8f4647c2322065d8b346f3ab4db7352a426170330a86a1b58f69ce47519179dcbb24b29be88056c0a1fc760f5c25ee1084dfee007bf159cf0addd214b33559b1a617dd4351105544697814a09fad13003e7beed9267b35d16513570b952ea18a970c994e78603ee7973fae188555c179b506041b5ba7fc56d9de363c6a03e3f4fe07e662a2602a08e179f1f50e4e02765e207e2bd412a97a67243ca477776580120f9c810ad0039e6ffd0bd912897e032b8077a428a4d75c1f0077f371e249827d5963881110155ab8f7dfed95056ec08afe4319e401d0278a80d230cbb12387eb9a5439ae9048af7cba37bcd67cac01c84c5b1ef6aa1a7fa49cacb6d011404637cfc2527a80621e2b38f83caa48a50c62abdb20637c7b6a945390f36b3172c8dbb5a2d20e3027c3297fa7a4354c89bc515ab908ceef4c648a46ce43173ed4139566066f15e060703217ab1c63f5f7157e10225ffe43ef33dd96c92826395511cfce706a05000d5d8467396f9b4540763162de6d76f1ed15f4a14bdb62456ed9e3556d71835012f7459d397c39727476c1743355119d5d6b273378f02edab397f0affac855d018af99871f1a81ff289619f40a09d15d171d4d761d8a7200c6d8cd48ebf6fc20055b61b9170005b53db72dac6a3b7a7a96150eb9f739809b61cb7c5df49020901ad9989de4c742e0567b6ae87ded7a6ff3df160a1a838012d6e78a7f4392e6204c24d1fe71fd3e37ead79137ac3996ca5079ab6dfebbde84f451c4de9283bfa023c493fcfcb62411f0e1c3125e86e25af6e92f5f34706fda9f06b6d147a620f033189308cfc9559a2db9c6cccfec3588ce6acd696b63d984f955e25f0d808fe0317a8bb9a2b758dc8dc6c2d3a481dfa7fadc8ead28240f5a6a6ba6fe1ec71480599ed", + "0x02f92e35058305c85e8459682f008504a817c8008353ec6094b6379a14b9cbf8d7a5d98db05792c5f01326da7b80b92dc4e85a6a2800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000002900059f6c72ee5ce1b2b9c73e7d388dffa93986a4049dc22f913e0c479f6c8bd3430000000000000000000000000000000000000000000000000000000000000003a790f058179d789827ddb24b18e7df50b2d27e54000000000000000000000000000000000000000000000000000000000000000000000000000000000000014200d81133f7072f9de7be316cb37295c7d7e0b99acb7ade87ea33d4fdfd92733501170bf3dd696f071b6ebb02cb748b471b435a2a705c13f52e1d88644d6f06d70223a176a28399e389f2c209914516ad5c5f9915bd75c7dbb22c39f0f76abab40661700fd6cbf626a837641052d54e311aa580d79bc48742f4536f53b2276a74060969c8e1833a1ef458024c0b4d282ef543e69974dde33035b3f90fd06d5dca031aadba1b435ad947af792c22c524226439fb7bc50361984f234571cd589c7d034e7d5e4ce4ae618ddcbfbdd664421917a276a66dd56a27312c0b9041c5591500fc2795bd95f370942290cf8b482f23bb9459d3d80308d801692bbac02f346901dfc0d89d1b5fe5b947dc7569cb09240e78b574f10762f7c53dffffd01abb26024327949f95379195caa142d6838ca7cf6b7b69a68991ba9d71a1f48c4514ef060d455929180ea7a40ac539a0f29f8bef1d1eb5c6de39348756549cab8de7b5010009a9791f063f1ba178babe1bfa274eafb3beeb4ce4692123b1bf12faf9c804bdd2dade38fb87f37ced539fd3bfb405f7057dfbb5c562028bf62af41458fd0749c4183398789153c47c8f1d43286d872426636624c123e31ea98e52bc56e7006e12fccefccab3acd7d80588b0d4e732a094ea8227dee98d1ba0926cec264806cf993ac8d78b6f6d71d0cb36a5933fd356f92e6bf84661fc524688ae0bed8e03d5bb61fb0dc1a02c8d4b3216df3d9806dde09d1ab71f909858ebe068be522c038ea3691f7e10a44d18532689aa7567fe64fb782e75cc7641a4295e0372cc4a00b0e41f4a48490d633aa6c6d453ec6619b27627ff5dc7a36e30b20dcbb670ad04842b5c556c46075328501b7aec46351c1f2233af413c3c055b0cbf5100139b0457088d5276c2d4c253f13c6756634cf6850bacbe68ba15682d8910208eb39701de7d26e6e9a2e2a770d14de1f4ae2bb2374fd4ea8c1b5bafb3400fa877a04600fb0a3e92060cd7c093225e2bd4d77bc40a3c8cf8eefec2230ae5b0f336927205795bf1e37ef50a30d362046c010ea76e3ed18cd21b1212fa4dda384c62b4370608a48ded70b47514e77a6c55565a8985b4c1f33cfbaf2d095e91d8090b4e3b040ccd36736a440eb1d930d0baf5a347bb67ea76e8557ecb2c992d78dba579ae06d97762d29a28319a7bbbccc7934e03e17664b5e21276db71ad24d99b6591f7046b1ebf2317465da2660e1b521cf2eb2231d3001c7cec431c0a2af892fc07e70346ed04e4007596ef048aeeb29d7d39c3086f1c229a9f428573861f2d2917e405ef78afe77d0bc2d4f1b9f35f2238e50a5dd4e8775055812d43150efb19e31303a0765483615d563cfd4b5e8f0750965ddcdba560b71b4bf8faaa08606731e306c1ca5ca2fe40eaab84f489fc4353af3cc10a1edfad5fd48769d8f16a9616f3054c956fd58e59099f44a15174964017a5b3e1022ba5da7e41b0e97aac21be23010464230f603c2d33ecd610801c0cfd286ade2a788e95e054d53c3c9ffad0290787d8bff19beea52b3ca272cc043395ffb0f251a7e589e10f0a1e7be5bdde2400617e4a9e47306a09a9485db24f2bf0240cdfcf490d2872fc86d52f6f88472d038a217fe936e5fd8ae69e283e3f469d7dd5b36f5746ed5ebff7f20f2c52ab8e008aba06edce9340ef4ab2a67c3d2e4695bd3ee5427e2e5c9e15dc069c8280f700d12c476fb95dca1d51e8a4f2f6d6f22cdb3c978cd5be8ddbbaa65c4acd1220019e53f5763fb8d0290d400caad0b600e3cc1979770ee75a9f5622fc02087504078f4ed52403e127e22b655118501343b367125541edb607a7a549f9d7f11dfa001bb0ae9b0d90499d277a089c2fe345ab13d82a9f7d28b6f809a6ad7e1f82aa028545ca6684e34343ea8589d0bc8e1889ac0b16680dc7c93b8f91b9bd610f02048537a7ab32eba351cb191f470af0a338e2fbd71e35130925941265aad4c51f02008f0e8e0b8da9ad369a1818be94598f6fcce43b9b263d7268ef9dfcaf7b9e01d2ea2b406d36a4bdc6204ccd1930ca1be108aea5ac52df9f8c94c32ef7bd0b01c6c97b53e53f531c5be54513b3f5622b9e4e18e1f267851c017d035a52025f0708e1a4e1c1a4091b911492975da601b80ac6c4df8d0d9f8253433b387eedea0514941adbee5f9f25d4799fb0a6df743afa05e01ab02597a604c5e7a70e85130030f5eecc526fccdcc7b0d828122c169bd365be2eba1fe4380af32609bf821e010dbd9dd1f355b2e26229fdfd3a4c9e876e84d8783630f4fd27667374aa41d0017b02e89fce64bf090041fee5284a5e88d1345120dcb4f7116531cd101a8522033a7930e5c81697a747ee9d765197b45bc38527f058a1ddc3f0177f9b47d02004585399aed85e8ed5b45f0747f723f8605dd2a74c90f6610f98d955cb5c32cb001b8388468f16b8ed3a2c324c65603217204c07fc7c5bf76a4a32373c867440034156d32e88b2f6c9557b6ab5fed0dd888a8faa251dbf095e00c5d00b42243103cfab", + "0x02f929b5058305c85f8459682f008504a817c8008353ec6094b6379a14b9cbf8d7a5d98db05792c5f01326da7b80b92944e85a6a2800000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000248005b02367334a5ffe4f054568042517fa0cef82bda2f6f7738718c9f825d8c4fe00000000000000000000000000000000000000000000000000000000000000030e9e685e9ed3807ec2a0d42cfb97339720502b18000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e07d0f4af005ec932fe77bfc369b38f106c8c843cf49e05c91fca9353c60b32c4006c67e913a359e026d606006daf1945d67f46a02399cf2fa586c3f09c16e4a8030a567be12a371cdce9ceeafa699f215f6732768c79e0fe607a92b6b4131b31032cb6df1ced02be0c7655bdd1a87f94ba5572b3a86c29254fc5739b613e2816043856a434027dc742074ee34615fa1b17a31ea527e67adda9cb342103f02c29068275041b5b5c92227fb0d0308f4371a8c95a16da5c841696da342408588c9f0189fe4da42b465f607cd79f88d71ab19c45fa169f3863065079420c5e74ac20061e6e901c94aaf229640bcad281c3b8ca767c7795e97efbebf1dbdfec9db9dd0258e71c8db8b33f6f8f7bd71bce26a248052531387983f6244a006fc5b732f602ac080b889d1b406518b6672eae811d775ab01506151a774dd016f80da5ece503510512243a9f796a0c9950f46eb339ae7d2b4549cc72b8517a85c64f27d2de06d25b97fe8ecb391c9fecf95247d09a277a1cf52918eac88ea06ed864e128bb004f082b6f981dc9ba95dc67e43ae9dbe683fd38e9162e1780a58a432fb0603802bc4a0bb06a599969e6e6eb980cc06ccc31e596a1d60d7ace55c9bac028beec02fbaf9e98ad17f08b2b5dd5ed9767bc423044880ae50585b17edf0bff9a556f07e17bfb2c07c39b579e0b40baf191ab6d5810ec317698f03ac274ba02a4466b06b78199122f0bd640cd369cc086b8e847554671934b0e255a8ac7bbc63fa94e02aae0f3cf62205e122e0baedd04ba6b750c041ba2dc61fb91f1f2988607e65701d694e41cfc2213b2101e64b4ad306860a66f0f1a8f26057e4c735d4dd0c2f804e3d2834fe22f399ff510ca97452d2a351057470e6e8859c8c3a8e32d554738018058062d191e2ca33688fa6559a041b2c3ecc8dc5303dcd210916af8083fbd02db9062812ab5962777e9c08308471203466815049122d3294828ac47548c650637cc629ab8a34eab6bb1ee6a1e5fd82223d12e53ce73d336b72dfdd558b876039264b4af7756f0f24586fedc2a82203934bb72958fbdabf2d3ea972686ada401e900509e9eac0882d00d7fe069eecd76c0550993f759de7e8300892f132e900185b9332378bde62cf2d904e88c9f47b30dd2dee6b8a2b866479f257d5e83c902b3ecdd30a9a2d247f3539bdff03a5c765a2e88f1b3a7a45c5a8c4058ca1e310474e15b05df7af618fd502553c1b82f93df9ff76ee6f68b64410b6308e5d508062f5706229614eb66bd4c9631c5f5941a54a346a567281735be905f3a63c7850789b435ec89e729f8ddcaedc0203cfc29262c67a681322be64f4c960fc8308e078bb32e668d1cd3f7008c740363bf4bbfce632087c9d0fe9c778bebb32b72d302831d3b4978f0a871558d1ad1d1c9727e7bf1e9432bed7423c3051f0fb150ee0715eaa1a41c916fd2ef5d801c5d31dcd5cc1dd451779ef25ce6de34681c25fd019e0ebed03ccb77d6a0f75184ed2aa626b3fb42e68a691ebb58e31aa21d334305347eb9316f422348fca8db7ff225589ec1dbd46eedba9ea04657ec1638d767024a86887134589305c460e1d4f952ab5a5c04e43ae7d691ca908b52caa3f78001caaa11545983677c0d9a75fc8334ffceda930043d6f8bfa93f72e684f8739d067be2137a150285394f8387f89fa845ffed996feea70abb8599b4ccaea3fd9f018c8a9b7bf1c3d703e6a17b9c0665f21ba342627b5bc6dfdb4915ef590f6c4e0218a145f5eae986e049bc671ce8e4e557e671c167067a23368fc267e03459fa07a02f604654d75acba9c68f849c7bfabd395b857a64dedb7d9d6f71b112b50a0661759f2ed2451c3b020a30c1d0e420691f02151efff14a9e88cffbc6b82d8a0454da2c05ab86975070ab807dfb5bfffb392db4eac98b45cf40c2d868f6781f03ce60c2f723d4972276753c9670c19e21fce7ad160a1289a8a26c98beb0b23806632915af610c6b3ebabc942b3c6a1c374b7fd79b33e293a6ac8f2ba107cbdb02ff8f4aebde1a820000577ead1d9c503412f3a2d74b4b39d158f067bc5b27380718696f8ce50ae7af8af5d0a00564c0de99acf25ef5b1f2f454499ac17b657603ae531c23ae4515f1fd49b65d46dd08b0ff5f4606bdf230c83026706d7a218504c68f090c880b2f42c103b7e5a4b771c5c542dff302b49043845cb0af83078e00ae4061251b91ae779e15e5e38b8cb61f66b3deb998f50b0d24beec49ec1dcb063ca20d0565f68b7f05f04a23b48316b89373fd6d9eea233e78f9061891bcaf02462015e00abfa78155ecf08c4ce5e4504598c1ff3996f191f67ada8f8b6348021ae3bb500d78d1a2e24c874113f17d93f3b2b2af7e1cd9873e5d7f50fb69cf0560ace7e5617bd80d3453fe6e32dd558adfeccfa96173acd00b8a12cae739d702a004586f36f8e94cc05a5c1822b7b974a307c025ea8c7fedbdfd308b2f1c7a02fe6b450ab19d6653c49d53ca33be4e693969ff9b9b5292520a6849cfd76c9707a769", + "0x02f92535058305c8608459682f008504a817c8008353ec6094b6379a14b9cbf8d7a5d98db05792c5f01326da7b80b924c4e85a6a2800000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000200001e072e3ba9a7773e1a53bfe18f2e3f790ccf86550cb90a738a60eed241e4d7700000000000000000000000000000000000000000000000000000000000000031ffc6e7bdea215ea5a327e868708bcd1f65e001800000000000000000000000000000000000000000000000000000000000000000000000000000000000000fa05b805a78002eaf459e4327f40018c1bb50c984b62f5f97ee79b35603be43a740095ce72a6086f9df5a8cf5142935dcf643a1987fa4fb09be85edcc4e487c372029b1896117b8f00da39145d4951ca306be14c02d50050c0b33cb7be1c3c2a73004b4020dd817fa810dc4021980d12c333bdbcdc95774b68dfe7900662c009ea019ebb0754eb1eec7cfad07c0ed0b56cd6ed2efc4fd746b7fe353d4619dd1e3c0381fbb14872d2f3093b5301d30dcbac8d069839247c601155f13eafb9a8a619061d8f1c2111b43b3c8be06fb410b92c872f559297c0c484e93bd0e4856e437d01eb537490bacb8440396b59eda1b8d23c81c1707f8379bfc0cf29c16d7cae6b01f2a2c392f86562b9587fd81b7acacc13ed81325159d3d465e069aaa2ac377604805ef71be5782f9989615f3b17de013bac81d178d777fc17f796124ac96fbf0235166ad720116e63f89efeb855543876242223969a6c7c788afbf29a3ed0540554f4aa088f4580d5f96b3d85bcd977e9844dd0a13b3011b7cd504ea81b288602f12cdea33eeadc14688973d82fda4da30366c411a2f43561d6bd6c8b8fd85a05f9ca03a9b4f2bd6f4d9859e0b5545773c6e5f437fa6d42dac33703f2064f5802c8bd873eda09c2a3b6b21c835c107c195434f210a96c80841c361f532966b905bd4bf01ff17cc6df87db3f7b82cd2e26743784a05075c89f1e096d18396e2a0460403362d299513ae278363f695ab045958e0559706ac2c3a329862b384f9700892b30c558d25d6ab2b06e25966853a8123f4d45bbc8d309a82ff3947e668605f8926acb813dfa155138767277550aa3434e9b0eafb9fc1bbf62861ee012d6021ea60c1f0293bc55074361a53d3c68d9372de12a4af749922fbf0a9b5a5d670668f23ab6e346fddf5a6573c2e7db65b7813ba73c7297fb3003b9e28ec8925b017b756cee10ab699c80b7b739ed4e495dc07ca54f6df0e3f0736e27e6c21c7a00925e15580d6ec5cb3b5b9b89c1250256788390cb10dc4ae625a55367ddcbb4005a26b907ca2c23605bf4d6defec40c875c718c6d255b6c5a886775854f513e072194a72e0f368c80e7108c2e51b2b55edec497abfa10e4ce021b354ac4bf2a07434df3497f33276509b1f721531a6bca27f15646fac021fa8c0b116d70e948065518299825d162e14974e8f1c54f1661a7551c3afbf5b3ad54a9b7e26ab09b03d6482d2ca2d083f8415a4aca828d86432f81d8c7159f87837ba7c0018ffc54075f3fa1c4e29312f3253883c5662cbd31f27c245ecf6b62a35fb6be9e99bcd10211f27df6962f292c856952233236a8d0c9901dccfd8392e1b276ab157c065802a6d8e1fb8941ee2d08edf8df98ff67a606831af00b19bd50cbe0c985a7f33f039d50efc8610c0a28e3d58f357abc322bd1d8a69ae9fb31a97931095a5ef41a0798eebac952758ec15246351b7f282c78f0c9b849a0e3bcb118698a81cd2bae07dedc02bb89ad0e390c2fd7b4d8953aabee26bf6a3aa632dcbd175c57f1924306ffb1a303949b3a1a7ace69e58730e38354afe03a30f9a9f90cebecedbb8a8e00cfbcc6640753a371c4d4d4382a8a0a5ad7b8c9039e45302f13a18b591e811f058854ff4b6a4430307abfa7ed6647d178d9ae689cc20a33d0659897e7a3efe4015746673118f3742df08cf01f71f92266593776dcee27d286931642eb62b702069fb2cb85ac25816595606faa8b9adc8d68b678aae8b6c487e60f816fbf2bbd02883fe3a6a95e5f5b4d193573b3c818e0f3b0a440df8d69313a6245df6508ff043192afcafc5cc3057dfc685e361b930e14f318576ca0e58f1f0064eaec1014078ffd73223871959e085978ab92c6d7df1840e8cf9c08ff1e8b32b0174a84160742077c26e4c6980e4a9a3ed9397dea7306aa7cc9a5cc21e97899f299ebffe800c3d93ca1fa248f95bebb003cbaa7cab6e317f4c790ef916a7470b1eec6d5860068ccfa37358ad4d6334c001a7b2c414654e28f8b92f6fe81e385bc4003c05d0152f520c015eab110dfe760b6b93302d7e28d4f2def7791d70800b5e71b9c6c04fd43a6d869c96187d67b1d1226087c7a31f88f0fef118043451888eb219b0303555e0c11d10b7e3b6ff1ea5312f6caf22e5679665d63d10f3e60929f4bd44a04eacb825f5ae19e297b7418b125c59ebafaf418adf802c6cf3c07e38120397f00cd7808095293e06e624d4854a799c9316e94b1694f30ca36fb5071f1036e33022221b7fa99702ccf6ef06503e521148c0141601b05d2de146955372b49d5eb002d71df8a95c9165fd1e99124455506e6e2e91655049ce9cc396c808137b2a6012794a275b41191887446165a8f3d85f1cfe63e123503cb161240a5e9184ede017e4f256339af0de5cbced9ae082e1858a869c3e01f242f4abb7fc626ca39c9048ba0a93d1d83de0805177f64eeca59f97d06911a10de13c3069795e75ae5200677e0e834f5f0243a48da59501fa942387edb2796e9ec1682a90316d109e017020924", + "0xf8aa098504a3a2aa9b830f42409438af6928bf1fd6b3c768752e716c49eb8206e20c80b844095ea7b30000000000000000000000009051dc48d27dab53dbab9e844f8e48c469603938ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2da0ed39530fc56cd555d9edf1b48335964f6deeedc67347b21bbc2a5c98fff74a9ea00665d2ddfe662641426020ddfdd86e1b5724da802cfc2460067f8640ee17aaef", + "0x02f903d2052084318d34dd8506a7e5824f830f424094683913b3a32ada4f8100458a3e1675425bdaa7df80b90364b87b0b4c000000000000000000000000c1c6805b857bef1f412519c4a842522431afed390000000000000000000000000000000000000000000000000000000000000060000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000002c4ad558ab9000000000000000000000000e34cfa1c2dd8aad94083335c9c668891470b4783000000000000000000000000e34cfa1c2dd8aad94083335c9c668891470b478300000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000001215be41b7f978000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004e818c23300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000644ab3940000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a0173aedff223dd364bf83f60d06377defbedc8eec888bc27bfc96fcca77cae06ba07db9ad843372885ca8f8cbf13f9b70bcb1d48270755e9cc5c22b7302af87ddc5", + "0xf86d819585049588ea4382520894092ac2bc42681b3ec6f4c79440dd6523b333d33488047425618743507a801ca050ddf80cba14a853de23973684377163521a055bcc2207c46784c6ab25bc6819a050135772b960805aacbc473a893e41be1cbb168311e0106c9362481291e5d143", + "0xf8c91285049588ea43829c669450b96c4374efeea0c183d06679a14e951e33b4dd80b864428dc45100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000f4b2cbc3ba04c478f0dc824f4806ac39982dce732ea0d4b02d3b09b9f5a1e8f5f12e93b6239ae6a16feab2cf9b4d5ff57a7563145153a075dca01d7467d4565105b6d919b295800d52a9e10d5d1fb4b88c6ca48b9143ef", + "0x02f8920581ac85049588ea4385049588ea43830249f094d8246f9c6cc0f006de446ab90a787942ceaead7480a47c279171ed5632bd9328325120a0fda3c3a4a9c50c52415043f5bb37efed86466eed94ddc080a0f031b5a51de8a493317db4a718533a7bd4a58f9a2f69f36d12bb67e46cd03ab9a03aaad83b38ae539f075cb2adee1fba5df9ba5d95eceff2989842a3f479c1f95d", + "0x02f89705538504808a64428504808a64558302861594c3511006c04ef1d78af4c8e0e74ec18a6e64ff9e861b48eb57e000a4b6b55f25077d9197bbc1b0ecdd8a4b13859406fc4beb908b708608c780fccf43a7a52ee0c001a04bdc1d7aa306f2ccec800d96f31320dfc74e2de52fcb4dc71fb2988e5566f45ba0109eae4d06bd8cada7f5785c8f36d93f75df5883d80d335cde986e76e2856bc9", + "0xf8880f8504808a644282f422945a94dc6cc85fda49d8e9a8b85dde8629025c42be80a4a0712d6800000000000000000000000000000000000000000000003635c9adc5dea000002da01f92d12e105343183ad791267f02e00374915ad4232a5a3734e4a153ceca81aaa03c11480d0055fbd8135ac220ae1eef9dc704597f11e45f7aabdbacdc8ca97ba6", + "0xf8b05c8504808a644282d55694fad6367e97217cc51b4cd838cc086831f81d38c287b1a2bc2ec50000b84440c10f190000000000000000000000007e1f1a7afb223208874f93b41449d080d76e0a8c0000000000000000000000000000000000000000000000000000000005f5e1002da0118b30965cc27a1336b68e3ff927af76a80cfb509dfc65ff83631758dfc41b8ba015f882ff83615aa7902f1f150d3833e2fa67f06528ba2230f36355bdda2f86aa", + "0xf8a95d85073109ce3a82eb869407865c6e87b9f70255377e024ace6630c1eaa37f80b844095ea7b3000000000000000000000000889cd829ce211c92b31fdfe1d75299482839ea2b00000000000000000000000000000000000000000000000000000000002dc6c02ea0cb2ee441ef991e62306d88b714f31a947906ab93f91d689876949c1f3e9e9bd0a067b9d5532a437582ec12f3828741584f91fd3d9cfdadbca214c647692aa5dc89", + "0xf90131048504808a6442830186a094e93c8cd0d409341205a592f8c4ac1a5fe5585cfa87470de4df820000b8c4e9e05c42000000000000000000000000a9369e95caa1ec951079acce313520e7b77d5d5f00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000002da09525b047b3ba9895b340151a89ea622c5e72c0b82f7517d914931bd158d08e29a01f33441185d51b0bc2dd67e33bfbce23070b659273f513d5561baaee40b789e1", + "0x02f8b705058459682f008507ddfb85da82d58694b93cba7013f4557cdfb590fd152d24ef4063485f87b1a2bc2ec50000b84440c10f19000000000000000000000000a9369e95caa1ec951079acce313520e7b77d5d5f0000000000000000000000000000000000000000000000056bc75e2d63100000c001a0da0de0df5c0ff8dac76e92af295552b74c1d5a24599497f151cc446f32e230d9a055142faa2197abd59da3b4e453bb8c702edb9e598d44ad47440e8aadd5ab07f5", + "0xf888108504808a644282f422945a94dc6cc85fda49d8e9a8b85dde8629025c42be80a4a0712d6800000000000000000000000000000000000000000000003635c9adc5dea000002da01140423c7aab99ababa4187d25eafb5b83f596a194a6fe1483393255631d6022a020f01ec01574b05cb2a62c5a376bd2d25265452df5de4d6691bbddd4f676ee51", + "0xf889038504808a64428301a41f94aaac6f9d407591909f1602762806e657eb12e21780a4ba83d1a00000000000000000000000007c3fc57a61806a7308f0b1179be0f054e37947f22ea0057f16b89762c679619935349c1c59b2754a20c35375c8b52175816c50051a13a05d244cad676145fd27831c07c2789c4e28677980d6ee0b057a9db9bbe22d1242", + "0xf8b10a8504808a644282d5869438af6928bf1fd6b3c768752e716c49eb8206e20c88016345785d8a0000b84440c10f19000000000000000000000000e540f0591fedd571b0f393f420fc7a89219e801800000000000000000000000000000000000000000000003635c9adc5dea000002ea0ac8ba8b9396bfaa5ad3bc2933afb1711622a7380475d3eb5bc80d95858d48520a070958f0bb7a59210f4c1066908e7c1d0750619e8a872bbdf3c8ebe528c929371", + "0xf8b00b8504d2c0a1b282d55694fad6367e97217cc51b4cd838cc086831f81d38c287b1a2bc2ec50000b84440c10f19000000000000000000000000e540f0591fedd571b0f393f420fc7a89219e80180000000000000000000000000000000000000000000000000000000005f5e1002da0b5c15c31931e4adb252fb43871d3e92f16201d22015189c3519e3132c9b69635a013eb296441cca7b4473efce2e254c3806214d3213763a3a89dc51fa0d6fdc5ce", + "0xf8a94d8504808a644282b76194b93cba7013f4557cdfb590fd152d24ef4063485f80b844095ea7b3000000000000000000000000aa1603822b43e592e33b58d34b4423e1bcd8b4dc0000000000000000000000000000000000000000000000056bc75e2d631000002da0bdbd7114f50df257593dd512d151bf616fd0d8912a4b07ebc0398ef658f4c4e6a003e88fa2a0508ed0ef48145e96ac18378fe456b700484580ee7f6e95de2ba1f6", + "0xf86b358504808a64428252089442cc37539f2be1d208487334045c3067725ac40c8701c6bf52634000802da07cc93bbe005cf3f3f23ba7c96016764abefdd7aea738ce074806236d6bb110a7a030ee12bd4031f6631823dc8658c0b51cbdb74234699ae36ef302c47c7fe27733", + "0x02f901390502840a6afe658505a9663a70830186a094e93c8cd0d409341205a592f8c4ac1a5fe5585cfa88016345785d8a0000b8c4e9e05c420000000000000000000000007e91953591451abdb0a11ec0300ba01014f4ceec000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c080a02ba70904b4e844fd84c998eda238599929d68e3af068118bd498a05ed48bd7cda026f71bfe8ed8cf7abc663e92ad1fd942de3766c0970441ae9d1bdd315851ecc7", + "0x02f8710581a78405f5e10085049588ea438252089403312088b906497859c26de7164f7f365776f81c85e8d4a5100080c001a0c7fbd660587ee5eed5f101fd6992079f30514ec5c5701994b4bb674e5b58024ba011964125b1196fadb2f56c0222b65b634f1b01b98ada5d43a026fd258d367272", + "0x02f8b4058309a36d8405f5e10085746a528800830186a09407865c6e87b9f70255377e024ace6630c1eaa37f80b844a9059cbb00000000000000000000000020361bd0066f87a721d9b95cd93503c1210396ad0000000000000000000000000000000000000000000000000000000000989680c001a0be61ff652fdfe8ae3b1b53ff947004eecda1676eea16ffdac9660fee39fc2184a053fcb46ef2f99d264072f8cb6c9a698409a5f949dcdef0bab9b6b2a99acd1554", + "0x02fa015b96058302dced8405f5e1008509251bf38683315820943c584ec7f0f2764cc715ac3180ae9828465e983380ba015b24cb9054990000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000033800000000000000000000000000000000000000000000000000000000000003bc000000000000000000000000000000000000000000000000000000000000045a00000000000000000000000000000000000000000000000000000000000007ac0000000000000000000000000000000000000000000000000000000000000aec0000000000000000000000000000000000000000000000000000000000000d4e0000000000000000000000000000000000000000000000000000000000000da40000000000000000000000000000000000000000000000000000000000000df400000000000000000000000000000000000000000000000000000000000010180000000000000000000000000000000000000000000000000000000000001328000000000000000000000000000000000000000000000000000000000000000e01e545e1c48f91da2516ec5188c581ffa34b44544e5b4d4637149d91099df922d04388d5e00aa25d0d7a3eb6e3514f75624b7d84c0a675e83d36e65748d8a9c33beedb71d6377745a91e41202ff61eba514a1bbecd1576540bcf3e3511230ad140000000000000000000000000000000000000000000000000000000000126cec483c466aa127f8b687f694c90eb3a2bbf7fc6e480718dcb88caef20f9ee2d11e000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000035b7571ca144185e5da901bfc28cde8afa68f984d625a727babccef8e9b098379ff49fc7c0ee2243913298b62d52a6ee35dbf60fba2372c338521c621723ca4af00000000000000000000000000000000000000000000000000000000001c528b0000000000000000000000000000000000000000000000000000000064529c0b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a12000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000eee3412fb24ca52c696e567b60067828b321bd4312b005dba9e24f185d646c5b7571ca144185e5da901bfc28cde8afa68f984d625a727babccef8e9b09837900000000000000000000000000000000000000000000000000000000001c528c0000000000000000000000000000000000000000000000000000000064529c0e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a1200000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000009e377f325dbb87de8cb9b64f1b669de1713ec78fbde2c63be60e484a3116d49400eee3412fb24ca52c696e567b60067828b321bd4312b005dba9e24f185d646c00000000000000000000000000000000000000000000000000000000001c528d0000000000000000000000000000000000000000000000000000000064529c11000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a1200000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002df70000008df88b828698830f424082ce2f94530000000000000000000000000000000000000280a4bede39b500000000000000000000000000000000000000000000000000000004a9b5bcc983104ec5a06fc6d4c6d9a65a1978e3ae115a584bc1079af980afc74d7fb82237bb227cb3aaa01aad9d6a6c7ad6fed4eceaa019e061fbdc9a0457ff3f33d7969f00213460cdea000001f2f901ef830735fd830f42408302f9b894b75d7e84517e1504c151b270255b087fd746d34c80b901848ef1332e000000000000000000000000429b73a21cf3bf1f3e696a21a95408161daf311f00000000000000000000000032139b5c8838e94ffcd83e60dff95daa7f0ba14c0000000000000000000000000000000000000000000000000576f62f31bf18000000000000000000000000000000000000000000000000000000000000240d7700000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000a4232e8748000000000000000000000000b56d9eb0de21bc9ff6e9673e233bef831b932892000000000000000000000000b56d9eb0de21bc9ff6e9673e233bef831b9328920000000000000000000000000000000000000000000000000576f62f31bf180000000000000000000000000000000000000000000000000000000000", + "0x02f950a5058301fa8e8405f5e1008509414f7436830550b094845310000000000000000000000000000000000080b950340040bb7b5d03d37d147122e7233d72f27f00000000501c78dadc7d075813cdf6f76e123a281de9a10802d2bb8a80f426a125402cd9d0417a132ca4812896808808a26b5714454525164014512c288a8a22cd5eb000221190ef49508cbe2270fd737defc7e313939d9933677ef39b73cecccece32b82f034cee8b30699b5d7d708feceac6aed504bf81f607ed617b13eab482fa50fa09a846dc2b636aa6df4d589d37ddf76ccb54fdd8b7451283d3ba055e3ef65ee675fdd9932dd88fc2f942ccb5b440cfad0b98dc490cc45204139140059d0d11b408a70680f5319b2a387f59ae72f9d973afcf74a8d82c5c5d08023b6277709ff1253110a85e8919b3803ffb6b1b239d6b8cf4d9bf4f06d19cbff0760f76072e4ed92d4d96af0a4adb712c6c41f8a931ca93c6d24fdfc0dc54ef3f6fbf1e14374b5757db0663ed1b931a11ece79f608a314a7471f424da18047b85ba415e36513863c364bd04e79848d7189be409cab7c6d70d9c57964263e442fced4bf7d41fd5e44a9ecd3df3e6974f6a072a537c6e5ec368a6ea57b67e99a11cabdcf47ce0ae5cf6a1cf7aeba59bef4c8db8ba65d7a345abe5c6a8a08a045fdccbb3bc46ecc87584e1175b4a77c6d3cf45e7b3a85abd458e16b4324245d46d5859d3fac37cc9ad35c74b882b85e768976ef3f3c796be480684cbdef2e8ec0ce960808b104cd09f453d2b9a5fa82ec0fa2052c1ce4fb91a3413b15a2579d07d6163ecda6eadebfa4ee25757a12eec78b2fb2650fe24ad3bfcc41f12f0870e2e564e149ea91022bab52e00bb8af09a786b48d0e97785033d77a0c6908fe0fc31ef9fe9dc9c3fead7af8c50ebe169792631e07634ab4fe379f15abe2a12fc1a21540a774a1ff22dabbb51f279775e37adc536fc446b6f8896461e7583ee5e586c4365a784f68ceefdbb28f639530e57bc9b59b937ef62ccebc81b42ed5260b82a035c8860827e2c801d38004628cdca15776fda690c2e34ea3df0187da9f9d6c25d09a8b20c44f4405ce924e03bf3ac6d4de97ddd5e7542de4c207d879a6bbccccdff4b7c9d96bb5a5943b3ef04aa13ba9fcc5b7336f3f89e20cef4bbce1e769b252e681daf713eda026d5b72deb77fa80a8493627149c64d25461b12b2e30773a3d61a2d7758b376775e929725f929def353169cf6dea847f5e0f99855279b7d53d4ee09c574ed7c2b5ef049a9f13dd1ba9faa5fc2004d114cd09085aff308beb3a853e759e596a756f1f52aee14ff90d7613028beb7eff03cdd1da4f28bfad73d4b47376a7a96bbedc8d563b49cf05be4f077ab2682dc0f7fcad38ec9ecbb613c6abab45a06d7315a471508eb7b251ac515b7f3983177f715bcb11ff41d70bcb74e5c3cfd9c118d11159067022bf68a6a1f5d62bd8bd2969d1080d8bad6bba3f1c9f5faa78b9df81cde77631ead6680c700267818ae6de50a7c9689b5c3afc70baf92dfef4c71f55ee55244c916ebbcee519796d53c6e57b688091238e83ef707badbff9aee20f3fd939d934077de9a33c27bcf896f5fbb558f764961e9ceca8ff70bff05747f7c4df4ccb12d87dd2e0f3e7aacda7731ae33e919fe74d04c47859a33e4002fdfa9b0522742e8d9c737921b69b7fca75cac98e2bb70d514118f947d2f33346e9fd8a7d259ee0ef4b9c29b423f2e2297c99846cd8857fb70fddebd50a9471b10fdcbf74618886bec96de693bee2e23543110d70126e20afcb6cd66c6acb327a96a4d2be6de102af0dcbc406aa9a7feeaf971170222c562979fa666fadd82e30eaa331644cd29dea8de1557e3dbc6dc81eddb2fff992a7142eb556e4bf8c3b32c9144266219474023c83128790d5bfe664083fab38067d2031a5462587c0af0a7018d116493906a0339d8e2f412ece6b9274445277bc6479944999b99a71adbebfb87c53819ba6002b5172f0d996840b3a8ff70c7724be2d10f0f1e32af298a9394f515237c0c2acedd15b0452d79aa7b32f5cab63349d0b3a428dda569ca3a947ccd5ac33bfa68d4d94b9b4c9d2ef9d788c88e1dd0f8ebdbae7fd779bd53eec5a79d952f4e998754a0df3cd14a9962d2aadf49a13a98c173ed661d906bcaf0db6c74bb4c95ac7b2138c552e7ed867d3d5b939ebd69821c9418026a00534019de95b5c9c9c043bda5c52824a5cd2dc579c9d5938b3ebb3ecbeabde3b9b97c262563dc7c0e64f2dfe1889250237cb6a422f6b8e63a3ed341de09b5c8de9812c7f7c6727ff1ec2b029756f1ef5ff6d68b349659e34abc987791ffe044ccdaa2c306332e91c32a2b03ef36cfeffb58ccff6e65d3efcd5ad1d2ffcb28e9de5665e1c757a65779b7ec28505e4336f73ebaf15515095eaaa2107d6bf9c73b1d79999e850b0bf17a5db3d2d713325a663ae01899e4978ab0fbcbfb897b2f18e4351a2f71c0cc37e4df400f9fb155edb9956386f9ab8ca9f6cb39dcc69cf184a13cd770368e7a93e03736f5783adaa8882a867c2a5e75775781bae3b5997bc6f01b7c931e868230ece657d0b2bc729595f0fd15b7d28d86ae9e95ed4d3d345d09a3993aeb8351a1c7f6abfd1d649a82a77cc6f4b75b654f531399250bd6486f399bdf6a44b3c789b98eea96f34671cb672d0e644e02bcb31a2f84dfa6e0ceee3c6360be06a1a3c22d1beffc7f09ef586e59ad2efbadf08d575a5e7559475285d63335fa8da757817089f1ad454b6f079989864f7ff662fab54bf7faad2df396465fddbb0d279fbe3a78166c9a6fc9fbeaf53ac5cf030a4b249062fb766aaba73d672e7febb3fba6e2e50da2eae58d88be0616ba86dfd1a5", + "0x02f913f6058302fd658405f5e1008509414f74368303858694654e6df111f98374d9e5d908d7a5392c308aa18d80b91385d0f8934400006265c600002a00000f000000000000000000000000000000000000020000000064529c6f00008859ca0000020000000064529c6f00008859cb0000050000000064529c7500008859cb0000000000010064529c7a00008859cb0000010000000064529c7a00008859cc0000060000000064529c8100008859cc0000020000000064529c8600008859cc0000040000000064529c8b00008859cd0000010000020064529c9100008859cd0000010000000064529c9100008859cd0000050000000064529c9800008859ce0000060000000064529c9f00008859ce0000020000000064529c9f00008859cf0000020000000064529ca400008859cf789cb45a755894dbf6fe865204060409c10308488788a4289d2aa584228d80201d2a20354849c80175483fa45b524a01490191904690ee430c9dbf67e0dedf85fb3033c7a377fff77deb597bd67ef7daeff7aebd060042d68318215e89dce15ece6c8a119aa2cd9b9141d6d2010917dd899edff58318c93cd60900808491c8547de0d0c0177cd16d3fe922d33cd5609343af5187eb43fbc58b851f4c34cc3f47e5a0fed6d940e734a19acbea6991570b52f2e9599bfc1d82b384581aa075515ba940a3e23c1ee3c3812f4f77a14a55b35707dbebee65059408f2c9a8650140ca7a1239c42bdf343c5ec75da73b92cf5cd2add4a89ab50aeff9435e5c8f22697cdde4bcc3a1f0486b4a7944dd675091716b122cccb8b14ad0761d387e6037daaed0d5680180178b00d8467292b08396df228c50386565a7f052fe645efd578e80dc3f82472b3303bfd380a26d6724ca33d264ab70b366625e48eae9b08159835b91b0bf983acea5c9b6af00904b1b101e02080c5b8126fcb828fc02ea1871fc2701a0a81a81db75f67024c7ad0d45d0001bf875b35a37d614a5ddc257f2c985763d54f600720f796dc6a3efa2b28d24f13d9d189cb8bf7d5ca0c767b7dda1a943e58f1cc66af136c8fd45ac0b5a9269d6cf62d3dd596871232419d3062b54fe28a9ad5f61ad8db037100519e99e1197babd37103e991ca9447fce2187f9aa9e84fb9b6a3ab17a6e998afc1800726b03a2720a02c32a9f3c16347f5c8b3a5d2e231200281a75479817a0080812bde8b8d828a028822e6a00003c0e3f28ac9b86ef6a584e77af9ff5651bdb41b8be5f4dc7b06a230cf3631d7ea8485e7cf7191e52462a6616a046e69b48feaa57eeb0fdb85d47a6a263cdcd0f32cf77dd63f965b72c4baf2e5b1591ce123517b97f66a679e22de0b8028aa7fda99ddcd0ca3dbf20f68052f1e66aeada1c9e1e07655de617d3b6fe77f4270f529108998a7ac7a722d18fc2bc64e3e3529154a0ffcc7c3ebd672b3eb69b3e36e1edde0b394b28970b110ed4d8d6788cda2eb8b9e755198cca4cd48c10b1861dd913c08da958eeafbb12d46e915ceeca03aa78b5a43417d1216eac166f864c452bcf04b6cdd09481c56b5b08375979f6feb7641b448b2667aaba9c685b8c7370402ed207ed1ae236d58903292eb0aebdab3ab42403814db26eb8a48d9bf28b8f380188c506c48c1202c3aa143b16348f62088ed01ca530ba68a8a44e5d4061c2b9a5c57ac6a756ca029d3f0000e0e1072deeb071d3ba9698a067dbd3a160010109829b1e3d1a714c18e63f92a2c711f7613baa14bd6b34be71d5ba30ec0a73acb1a160727f9275e30df298551d5afa42ff9ba3dfe441da1751b3cd9ffe94cf75c61d71a74578445ce19a89db5b78742aa8a9baac2f2a1e0082d703797ee3a746f8e697e1913b5b2b7e2d138a88b329a3af08637f288f04135a08f3337d4bfe48fbe6e3e060eb1069baf60599823fb7b2f15814469d3849dd2e5dd0be7a7dca80480f80a86d4094914c14a47bfc9959bbe2bb812f72113d11010079c49e249b9a2d865d3892f4c566e129b445b0d51b044b9b73b8aa2d9ffd487bd0391bab453b6298ffa788e8b8338fc4b4b82d163ab8d8103788efe310d21d73bb59fd01355cb937ba74c05c3930993813bce294b0e503a342843665db252c2ce704425d9db66e0266ceed1ca7c8146b7a0fce14360486f5703b5c667cf57ccd9c0f45d35654c94cc686514029c0873c53548dd96368d7027fe5816a95bb527fa654a839e16340e3c899b2f5b1f6fbd60313bd5b605d3e9ea550b0602d82f64c1aabc5516198ff08daa9ef399b22ccb267e1a986c20569f2ddac93dd2c87edbe974f4375fff82a15ed7e3be6bdf898ec6e0a970912ed3984054dfa582bc5da0d22b13e7b75515d371cf7bdfa1030f9464ca957b0ac0d28c728544127a2f1e2f507eb60bc4e7dbedb8c3119e5da5cccf88d9e125d1101ca0768b3fe7306bb70d19ceaf9cda53494eb843e79d93872112d1fff37dab0c2d3296a95148556ad2fafd867bbe7fa18de3541e76cac16c78961fe236863924ea872fbbb64cac38a93fc8667e03cf9eac46b64b8c3ce3575fccaf6526575cd5d5ff0f34183cb2ab205ad6c5aef97c666941249ba3212619449425a6661dc76591146d603fb6219e7b7319800f8cc72c4d7083bcc71567e77b45ce3ca1b32d304e3d9e74e36a6866ce32ea58b5de0ed64feaa3ec9491aae7186aa02cec621ad604e91e26cbd793d19b1977015a6cbfb11d1fe464ef57d51cd1ba04cafff483dafdf429cbb700c41e1a0a090596537b37abec0f22f05f0b4e0e28f2fb6db2f6fdb62cd8c42a8796e373eb3d3b4f24bc0c673859ea67bc9b22fdf4f42bcf249c38fe3a05f93ef580523d914397e48f9ce0f5efeae5850643e53aef8560f913a602220", + "0x02f8b4058309a36e8405f5e10085746a528800830186a09407865c6e87b9f70255377e024ace6630c1eaa37f80b844a9059cbb00000000000000000000000069dae868ffde59560637e21af369a7bf1f84f03e0000000000000000000000000000000000000000000000000000000000989680c001a08816035c5176a9f1e564993be46c80b90b5925c3bb9bad3c5098f44df22a1600a051607e78fe767401331c400f0a28a8079da665d92ad32c54b2c07ef84f053772", + "0x02f90b7505827aa88405f5e1008509414f74368301008494ff0000000000000000000000000000000004206980b90b0500669689d17d3e71a334ef9a09a2909a6b000000000aed78da8cd6e93bd4efdfc771e52bc6d2488630cabe4523fb9665b2650943592b09636bac21664a339821a6420c85b1244b5296b2262963694463897eb44ad992253bd7e1b8ceee7ffe81c79df33cdecf57bd1ddbaa0d1d337158cb462e758e40dbde4bdeea1f78566ba8dc74255a2955747b105b314724515cdfd19d094f573602fc5a42224478956e1097e9eb9a1538db92d08e4ba247d4b58f38c77b63eeabbefc7ff07ef7785199b4f662ae65e63ed89c68bc8ec1a318a54b9d96bd998df050a2ba1b64500d80c6d4f4fe9507cd628259e284489581194f9844abcd9bd49c0bc31ff6d08a544621831a00b43d773572cc8323463f577f1cd6bd6848266ab02f4b3dce23ac0a0514c5b6be830c6a01b04fa77056c0593f2b386daac205778f7cffcbac59f5abeb4944cff4c3be2a63c290411d00067cea76bb479ed7dcdac7cb14ac7a33ced2d67414b068bb1c81f15039f6ed331932a80740c521a7131ed3e90cf74ea5eac95c557d9c82e4b6c8cf9699960599f342d50939904103009ee853217e58ddd8aa915b231fdf5a12b4e838eb707e9bd0d0b14f6ab5e36b10f46f6308c0e204ecc76307683ef881758ed683af9c8e965f814d9c92db2a9be6cb53839da142068d014852ff8b12114acf9e1c7a1e322f65863792a819b1c47bb2b19a34e1f3391ded904134006d7ac6fdc2eae7e9d6489ff4d06a33456cc5f4d69db207981331bf9a9d7750872183a600dc23c51c1937b87d63f49e42544ef9ed8534c5ada2abb633bd962491f3c1a5024f4814d73eba3c57824bf338fc78e85c2e62ebd022cfaf6f4eb18ecc1fdfb3cf2ef3d3f8d65276417300567360362bebbc868b8e75c28f38ea4c1eba9be49b9b22bcc6e20bd53bc0fbb61c32680940112d9cd66151fbc29a27be74b542c6fe700446833994efbadfbe676f09f9742a64d00a80771e7af1344de09bb878427c3f20cea29d7d8abf5d1bead5edf5d52f402f53ba218336001caea0abb227af3bfa5878afe154e5d149f971bf13bfc2d34e062d9e31483031870c9efef7cafd0873f70faffbbc0889e7d86f9035e5d8ee205e9365ea522a89558edfff6b23515cfbe96115f20d1e3883f274f985b0372e9fd70aceae968aaf93107547a732c6033e36ef82f600b43b89fba36d0c33acef28a8cfff121c33802b4b3c5c7c15c6d9595151fb78a21932880120dfa799d85c4b0ac725599786d0f8a59f62771f66bfe8c16014f285904a28f21dc8a01300234362887df9ed4126d14957d9e3780f6c9ee1e6cb94bc3d70d9a9edf663278312c8e05900feb078541ac2a66a9df1ab384471b17b3ee8296376bc6c54336867627009ed6508197401e0c9acee1d1c13ad8c4ad3b744bb2e934e4c15dcb39dc940dd1e9f52793da42f0519740320b2db4aee2183df1fcd2d4b103c48bcf4373f2aa9ee8d10a7b8d0a9d033b1775221831e004c646ca7aff5c97973d85e3633a8e86632d3aadc507fbc2cdf1afd9096d7b88827515cdfd3fdaa5a62bba585fc9085fe394e2a8123a929c96c3118cb1acd788d820dfc65a15df03c00895fe3b45a4a0d099275b4c9cda8d30896ed279128839ebb0a02bf9c2f48b68840063d01e83f575a5945591aa69bff3eaacd5f882a1eb5d8d1ae74d18dbe92eeda202c49820c7a0170da8cc6ebdb2ed92163c0c625c4a910a6efddf7d0f0f8b2c3c59854d1a51be81b9041ef7fe72b0f556383fbc8dfca9d6f88d709a96916fe9f1ad9c36a234b6f9f459bb2691d64d017804fb2a4604ba5264359e10eafba9496785911c9ee0a93f0c7eb89e94130f2116312c595459f98c27e7c5cab76a8642b6820d4a8fdf8752e42c85931d55ac251cf2b276462dd76413f00cae0c2067c2a901801ab645a9e9783dead70e50225875bb267d66b8fb36d77f242060300b8126eccbe9cc1f7be94c13526b371a1b459f063d1e9aec938962efe49b5b6d917c8601000ddf86c07b142cf3aaea0ae8f45b5067b07bef87d7f79e19ad98fcc328395bc531590411c002bd1869d5ab13cbae8404e3f49b440f55b22f5f3ac8f9dbaf681a5ec1781fc54c86008005392ee4a0eecdd19e5336f38c29fd519fd1ae336a55f60f7f29c754f77c02bfe7ec860180017eb952765f350e391ca5c268832849ed61c5ed6572a4ac254617ea6c71bb13be706e84301d42a2ead29c7d189545a593efc54d213731a1bb3ebd529c680db87adc5a05d300280e5f6e6e29b225fb6c5ed2279666ccfc1ba6ec96c3c95a735d243045d582ac2ba90c14800c65c55f2d1fdb8c78af4ae0ebe8cdcdb0e5f1a4b7d01fb63f8c93edafe27e1451164301a80d8a949331fa100ca4791a334da7b19464ea3a8a21537b7da4139339bc1d752ff4106630098d594cfce1aaa62e9285e239814c72a1561fba946c49843e436593e1683471d328807e0ec8fcfc86783ef46c29985f61a15e94dd30b4d16c739521de2fbbd240a1a04932183d700c83dcdb59ae7ee27e322383fc53b2ae97b300e35f6534a7cd5ca256a4396e0b33b8907e9b0265ffca7ce319f75d4bb9b0cb4cc505798a3a1b6235e823a46b4d226fcaadc05e300e8cb079b67afeffa2ee0fb2633d239a3ae1ad6a1877c10f77753254473fa095210324804a0bbc43413a5f588e6fe7d5fe316c6198739e49076683bc24851e525dae904d11c32180fc07da65441aa79e6b1e8fcb1ceba42c69480ffc928ce30b29058c230ae51dd3105329808c097382e23aa70f250f570f51e9e9d36f902cfec96a53af199", + "0x02f8f40583013a798405f5e1008509414f7436830156c294e6dfba0953616bacab0c9a8ecb3a9bba77fc15c080b8849aaab648a3c315858d02541ef1aa93feda9c3a1245a05dcf8db82f60edf29b666edb1390000000000000000000000000000000000000000000000000000000000087187ccc400fb13ebf36bb86163429ac697486a69f6f5fabc79aa9e36b3c7a6cd030f100000000000000000000000000000000000000000000000000000000008859d7c080a05d427735b37c30edc668e5346a1cb593eb33fdee3a11221481bf29dc7666958aa00a03dbb34ede5e69e754efaf86bc19dc0d0a6235d04d8aad78847df1679bfe2a", + "0x02f9567105138459682f00850473c901ce834bbfbc8080b956176080604052601b80546001600160a01b03199081167316fbb520f1774dd702883867c5ef6cde625fb64b17909155601c805490911673d06d855652a73e61bfe26a3427dfe51f3b827fe31790553480156200005957600080fd5b50604080518082018252601881527f41727469666163747320627920456d6d61204d696c6c65720000000000000000602080830191909152825180840190935260048352634152544960e01b90830152601b549091906001600160a01b03166103e8816611c37937e080008083733cc6cdda760b79bafa08df41ecfa224f810dceb6600189896002620000ed838262000986565b506003620000fc828262000986565b506000805550506daaeb6d7670e522a718067333cd4e3b15620002485780156200019657604051633e9f1edf60e11b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe906044015b600060405180830381600087803b1580156200017757600080fd5b505af11580156200018c573d6000803e3d6000fd5b5050505062000248565b6001600160a01b03821615620001e75760405163a0af290360e01b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e9063a0af2903906044016200015c565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b1580156200022e57600080fd5b505af115801562000243573d6000803e3d6000fd5b505050505b506200025690503362000366565b6200026b866001600160801b038716620003b8565b620002768462000464565b620002826001620004ae565b601892909255601955601a80546001600160801b0319166001600160801b0390921691909117905550620002ce9350600080516020620055f78339815191529250339150620004f59050565b620002e9600080516020620055d783398151915233620004f5565b620002f6600033620004f5565b601c5462000310906000906001600160a01b03166200051c565b601c546200033890600080516020620055d7833981519152906001600160a01b03166200051c565b601c546200036090600080516020620055f7833981519152906001600160a01b03166200051c565b62000b9c565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7690600090a35050565b612710811115620004025760405162461bcd60e51b815260206004820152600f60248201526e45786365656473206d61782062707360881b60448201526064015b60405180910390fd5b600d80546001600160a01b0384166001600160b01b03199091168117600160a01b61ffff851602179091556040518281527f90d7ec04bcb8978719414f82e52e4cb651db41d0e6f8cea6118c2191e6183adb9060200160405180910390a25050565b601180546001600160a01b0319166001600160a01b0383169081179091556040517f299d17e95023f496e0ffc4909cff1a61f74bb5eb18de6f900f4155bfa1b3b33390600090a250565b6013805460ff19168215159081179091556040519081527f38475885990d8dfe9ca01f0ef160a1b5514426eab9ddbc953a3353410ba780969060200160405180910390a150565b6200050c8282620005b860201b620022971760201c565b62000518828262000613565b5050565b6000828152600b602052604090205462000537903362000682565b6000828152600a602090815260408083206001600160a01b038516845290915290205460ff1615620005ac5760405162461bcd60e51b815260206004820152601d60248201527f43616e206f6e6c79206772616e7420746f206e6f6e20686f6c646572730000006044820152606401620003f9565b620005188282620004f5565b6000828152600a602090815260408083206001600160a01b0385168085529252808320805460ff1916600117905551339285917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a45050565b6000828152600c602052604081208054916001919062000634838562000a68565b90915550506000928352600c6020908152604080852083865260018101835281862080546001600160a01b039096166001600160a01b03199096168617905593855260029093019052912055565b6000828152600a602090815260408083206001600160a01b038516845290915290205460ff166200051857620006ce816001600160a01b031660146200071f60201b620022f21760201c565b620006e4836020620022f26200071f821b17811c565b604051602001620006f792919062000aa4565b60408051601f198184030181529082905262461bcd60e51b8252620003f99160040162000b1d565b606060006200073083600262000b52565b6200073d90600262000a68565b6001600160401b03811115620007575762000757620008e1565b6040519080825280601f01601f19166020018201604052801562000782576020820181803683370190505b509050600360fc1b81600081518110620007a057620007a062000b6c565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110620007d257620007d262000b6c565b60200101906001600160f8", + "0x02f902f205148459682f008507bfb7649e83011bfe94a6482ee4afcd6681d0e60bc5f1f05edb1b585dca80b90284ac9650d800000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001e474bc7db7000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000642998dbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000037697066733a2f2f516d505758776662754e4378384a4c47524b5645524532466e5139684a5a346d3756766b3673665263635a6a62322f3000000000000000000000000000000000000000000000000000000000000000000000000000c001a04d066618685e4b27eae175e5a7a632f6d59efa979bc01f005fb5591ba587660da029083f2a4d54a76b57b32ea1d1389671bfb1a6d9a8a243a35b6d3b9d8b1252f8", + "0x02f8710583012c1980850470f912ff825208945cc0dde14e7256340cc820415a6022a7d1c93a3587fcdfcc79b1a06780c080a0a7abeba60a2a098fe89f78a9e95ca2958c278c4a2c17cd83ebe053f0afb88e63a059742db5b55927154d73fe8dff5cd2d790b8650f6b68790306a20f0928512753" + ], + "withdrawals": [ + { + "index": "4466251", + "validator_index": "418388", + "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", + "amount": "1927254" + }, + { + "index": "4466252", + "validator_index": "418389", + "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", + "amount": "1936801" + }, + { + "index": "4466253", + "validator_index": "418390", + "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", + "amount": "1882324" + }, + { + "index": "4466254", + "validator_index": "418391", + "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", + "amount": "1934493" + }, + { + "index": "4466255", + "validator_index": "418392", + "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", + "amount": "1944116" + }, + { + "index": "4466256", + "validator_index": "418393", + "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", + "amount": "1940345" + }, + { + "index": "4466257", + "validator_index": "418394", + "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", + "amount": "1918177" + }, + { + "index": "4466258", + "validator_index": "418395", + "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", + "amount": "1913127" + }, + { + "index": "4466259", + "validator_index": "418396", + "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", + "amount": "1862609" + }, + { + "index": "4466260", + "validator_index": "418397", + "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", + "amount": "1922414" + }, + { + "index": "4466261", + "validator_index": "418398", + "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", + "amount": "1940750" + }, + { + "index": "4466262", + "validator_index": "418399", + "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", + "amount": "1919017" + }, + { + "index": "4466263", + "validator_index": "418400", + "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", + "amount": "1901929" + }, + { + "index": "4466264", + "validator_index": "418401", + "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", + "amount": "1871194" + }, + { + "index": "4466265", + "validator_index": "418402", + "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", + "amount": "1855146" + }, + { + "index": "4466266", + "validator_index": "418403", + "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", + "amount": "1907921" + } + ] + }, + "signature": "0xa2def54237bfeb1d9269365e853b5469f68b7f4ad51ca7877e406ca94bc8a94bba54c14024b2f9ed37d8690bb9fac52600b7ff52b96b843cd8529e9ecc2497a0ecd5db8372e2049156e0fa9334d5c1b0ef642f192675b586ecbe6fc381178f88" + }, + "proofs": {} +} From 93e7c947d270c8a3fcf1f79b2ac98ad1a6cd82fb Mon Sep 17 00:00:00 2001 From: thedevbirb Date: Tue, 28 May 2024 11:55:38 +0200 Subject: [PATCH 15/15] chore(relay): cleanup --- mev-boost-relay/services/api/proofs.go | 4 - mev-boost-relay/services/api/service.go | 1 - mev-boost-relay/services/api/service_test.go | 160 ---------- ...mitBlockPayloadWithProofsDeneb_Goerli.json | 294 ------------------ 4 files changed, 459 deletions(-) delete mode 100644 mev-boost-relay/testdata/submitBlockPayloadWithProofsDeneb_Goerli.json diff --git a/mev-boost-relay/services/api/proofs.go b/mev-boost-relay/services/api/proofs.go index 769ea4fe..eb5ffb17 100644 --- a/mev-boost-relay/services/api/proofs.go +++ b/mev-boost-relay/services/api/proofs.go @@ -43,8 +43,6 @@ func (api *RelayAPI) verifyConstraintProofs(transactionsRoot phase0.Root, proofs rawTx := constraint.RawTx - log.Infof("[BOLT]: Raw tx: %x", rawTx) - if len(rawTx) == 0 { log.Warnf("[BOLT]: Raw tx is empty for tx hash %s", proof.TxHash.String()) continue @@ -58,8 +56,6 @@ func (api *RelayAPI) verifyConstraintProofs(transactionsRoot phase0.Root, proofs return ErrInvalidRoot } - log.Infof("[BOLT]: Tx hash tree root: %x", txHashTreeRoot) - // Verify the proof sszProof := proof.MerkleProof.ToFastSszProof(txHashTreeRoot[:]) diff --git a/mev-boost-relay/services/api/service.go b/mev-boost-relay/services/api/service.go index 040baa87..2b25da8f 100644 --- a/mev-boost-relay/services/api/service.go +++ b/mev-boost-relay/services/api/service.go @@ -1980,7 +1980,6 @@ func (api *RelayAPI) updateRedisBid( return nil, nil, false } - // TODO: verify proofs here slotConstraints, _ := api.constraints.Get(api.headSlot.Load()) if slotConstraints != nil { transactionsRoot, err := getHeaderResponse.TransactionsRoot() diff --git a/mev-boost-relay/services/api/service_test.go b/mev-boost-relay/services/api/service_test.go index b01b55e2..e93007ca 100644 --- a/mev-boost-relay/services/api/service_test.go +++ b/mev-boost-relay/services/api/service_test.go @@ -705,166 +705,6 @@ func TestBuilderSubmitBlock(t *testing.T) { } } -func TestBuilderSubmitBlockWithProofs(t *testing.T) { - type testHelper struct { - headSlot uint64 - submissionTimestamp int - parentHash string - feeRecipient string - withdrawalRoot string - prevRandao string - jsonReqSize int - sszReqSize int - jsonGzipReqSize int - sszGzipReqSize int - } - - testCases := []struct { - name string - filepath string - data testHelper - }{ - { - name: "Capella", - filepath: "../../testdata/submitBlockPayloadCapella_Goerli.json.gz", - data: testHelper{ - headSlot: 32, - submissionTimestamp: 1606824419, - parentHash: "0xbd3291854dc822b7ec585925cda0e18f06af28fa2886e15f52d52dd4b6f94ed6", - feeRecipient: "0x5cc0dde14e7256340cc820415a6022a7d1c93a35", - withdrawalRoot: "0xb15ed76298ff84a586b1d875df08b6676c98dfe9c7cd73fab88450348d8e70c8", - prevRandao: "0x9962816e9d0a39fd4c80935338a741dc916d1545694e41eb5a505e1a3098f9e4", - jsonReqSize: 704810, - sszReqSize: 352239, - jsonGzipReqSize: 207788, - sszGzipReqSize: 195923, - }, - }, - { - name: "Deneb", - filepath: "../../testdata/submitBlockPayloadDeneb_Goerli.json.gz", - data: testHelper{ - headSlot: 86, - submissionTimestamp: 1606825067, - parentHash: "0xb1bd772f909db1b6cbad8cf31745d3f2d692294998161369a5709c17a71f630f", - feeRecipient: "0x455E5AA18469bC6ccEF49594645666C587A3a71B", - withdrawalRoot: "0x3cb816ccf6bb079b4f462e81db1262064f321a4afa4ff32c1f7e0a1c603836af", - prevRandao: "0x6d414d3ffba7ba51155c3528739102c2889005940913b5d4c8031eed30764d4d", - jsonReqSize: 1744002, - sszReqSize: 872081, - jsonGzipReqSize: 385043, - sszGzipReqSize: 363271, - }, - }, - } - path := "/relay/v1/builder/blocks_with_preconfs" - backend := newTestBackend(t, 1) - - for _, testCase := range testCases { - t.Run(testCase.name, func(t *testing.T) { - headSlot := testCase.data.headSlot - submissionSlot := headSlot + 1 - submissionTimestamp := testCase.data.submissionTimestamp - - // Payload attributes - payloadJSONFilename := testCase.filepath - parentHash := testCase.data.parentHash - feeRec, err := utils.HexToAddress(testCase.data.feeRecipient) - require.NoError(t, err) - withdrawalsRoot, err := utils.HexToHash(testCase.data.withdrawalRoot) - require.NoError(t, err) - prevRandao := testCase.data.prevRandao - - // Setup the test relay backend - backend.relay.headSlot.Store(headSlot) - backend.relay.capellaEpoch = 0 - backend.relay.denebEpoch = 2 - backend.relay.proposerDutiesMap = make(map[uint64]*common.BuilderGetValidatorsResponseEntry) - backend.relay.proposerDutiesMap[headSlot+1] = &common.BuilderGetValidatorsResponseEntry{ - Slot: headSlot, - Entry: &builderApiV1.SignedValidatorRegistration{ - Message: &builderApiV1.ValidatorRegistration{ - FeeRecipient: feeRec, - }, - }, - } - backend.relay.payloadAttributes = make(map[string]payloadAttributesHelper) - backend.relay.payloadAttributes[parentHash] = payloadAttributesHelper{ - slot: submissionSlot, - parentHash: parentHash, - payloadAttributes: beaconclient.PayloadAttributes{ - PrevRandao: prevRandao, - }, - withdrawalsRoot: phase0.Root(withdrawalsRoot), - } - - // Prepare the request payload - req := new(common.VersionedSubmitBlockRequest) - requestPayloadJSONBytes := common.LoadGzippedBytes(t, payloadJSONFilename) - require.NoError(t, err) - err = json.Unmarshal(requestPayloadJSONBytes, req) - fmt.Println("json", string(requestPayloadJSONBytes)) - t.Fail() - require.NoError(t, err) - - // Update - switch req.Version { //nolint:exhaustive - case spec.DataVersionCapella: - req.Capella.Message.Slot = submissionSlot - req.Capella.ExecutionPayload.Timestamp = uint64(submissionTimestamp) - case spec.DataVersionDeneb: - req.Deneb.Message.Slot = submissionSlot - req.Deneb.ExecutionPayload.Timestamp = uint64(submissionTimestamp) - default: - require.Fail(t, "unknown data version") - } - - // Send JSON encoded request - reqJSONBytes, err := json.Marshal(req) - require.NoError(t, err) - require.Len(t, reqJSONBytes, testCase.data.jsonReqSize) - reqJSONBytes2, err := json.Marshal(req) - require.NoError(t, err) - require.Equal(t, reqJSONBytes, reqJSONBytes2) - rr := backend.requestBytes(http.MethodPost, path, reqJSONBytes, nil) - require.Contains(t, rr.Body.String(), "invalid signature") - require.Equal(t, http.StatusBadRequest, rr.Code) - - // Send SSZ encoded request - reqSSZBytes, err := req.MarshalSSZ() - require.NoError(t, err) - require.Len(t, reqSSZBytes, testCase.data.sszReqSize) - rr = backend.requestBytes(http.MethodPost, path, reqSSZBytes, map[string]string{ - "Content-Type": "application/octet-stream", - }) - require.Contains(t, rr.Body.String(), "invalid signature") - require.Equal(t, http.StatusBadRequest, rr.Code) - - // Send JSON+GZIP encoded request - headers := map[string]string{ - "Content-Encoding": "gzip", - } - jsonGzip := gzipBytes(t, reqJSONBytes) - require.Len(t, jsonGzip, testCase.data.jsonGzipReqSize) - rr = backend.requestBytes(http.MethodPost, path, jsonGzip, headers) - require.Contains(t, rr.Body.String(), "invalid signature") - require.Equal(t, http.StatusBadRequest, rr.Code) - - // Send SSZ+GZIP encoded request - headers = map[string]string{ - "Content-Type": "application/octet-stream", - "Content-Encoding": "gzip", - } - - sszGzip := gzipBytes(t, reqSSZBytes) - require.Len(t, sszGzip, testCase.data.sszGzipReqSize) - rr = backend.requestBytes(http.MethodPost, path, sszGzip, headers) - require.Contains(t, rr.Body.String(), "invalid signature") - require.Equal(t, http.StatusBadRequest, rr.Code) - }) - } -} - func TestCheckSubmissionFeeRecipient(t *testing.T) { cases := []struct { description string diff --git a/mev-boost-relay/testdata/submitBlockPayloadWithProofsDeneb_Goerli.json b/mev-boost-relay/testdata/submitBlockPayloadWithProofsDeneb_Goerli.json deleted file mode 100644 index f275f171..00000000 --- a/mev-boost-relay/testdata/submitBlockPayloadWithProofsDeneb_Goerli.json +++ /dev/null @@ -1,294 +0,0 @@ -{ - "inner": { - "message": { - "slot": "5552306", - "parent_hash": "0xbd3291854dc822b7ec585925cda0e18f06af28fa2886e15f52d52dd4b6f94ed6", - "block_hash": "0x1bafdc454116b605005364976b134d761dd736cb4788d25c835783b46daeb121", - "builder_pubkey": "0xb67a5148a03229926e34b190af81a82a81c4df66831c98c03a139778418dd09a3b542ced0022620d19f35781ece6dc36", - "proposer_pubkey": "0x8559727ee65c295279332198029c939557f4d2aba0751fc55f71d0733b8aa17cd0301232a7f21a895f81eacf55c97ec4", - "proposer_fee_recipient": "0x5cC0DdE14E7256340CC820415a6022a7d1c93A35", - "gas_limit": "30000000", - "gas_used": "25875661", - "value": "71177763439091815" - }, - "execution_payload": { - "parent_hash": "0xbd3291854dc822b7ec585925cda0e18f06af28fa2886e15f52d52dd4b6f94ed6", - "fee_recipient": "0xb64a30399f7F6b0C154c2E7Af0a3ec7B0A5b131a", - "state_root": "0x74f74d15dcb00ba194901136f2019dd6be2d4c88c822786df90561a550193899", - "receipts_root": "0xb410fa34a1312626db3c41d325545e9f24e903d5dd9b9c260882aadb4c28fa8e", - "logs_bloom": "0x40f7484521e2f4f8001ed9b0810595c450380844af610944218104d21c220028aa6a150a86312b000040401909e548e71c6a05128a58607200103fc400346f6e9843c2e20c72a00d7bd8138a249a83208697c0d03d7633c18248a58fe88284240a0e43e782c6b0c1167a00ac9808be499950e8500228776980266490f21c9040b30a30b4922c3a7af850ba08f2000146ea850401e978038e1205094215025016ae8811166961477d68522c826c9a0d20228c822de2ac830503b13936b5e01b9f9532ec2322c70c491c1a21618533c284299b189207cf0e37f2c7a1930c6667815fd238290926265cc28095a0a0240234af3810928a962ad0264a4905018a02a1", - "prev_randao": "0x9962816e9d0a39fd4c80935338a741dc916d1545694e41eb5a505e1a3098f9e4", - "block_number": "8935900", - "gas_limit": "30000000", - "gas_used": "25875661", - "timestamp": "1683135672", - "extra_data": "0x496c6c756d696e61746520446d6f63726174697a6520447374726962757465", - "base_fee_per_gas": "19075240703", - "block_hash": "0x1bafdc454116b605005364976b134d761dd736cb4788d25c835783b46daeb121", - "transactions": [ - "0xf86f8304155e8535fad650928252089499e4530a9965dcaca8aad011714ce1446667e4eb88016345785d8a0000802ea0bef03fc632456d3b0f1506694c073c0c607a22eb6ac964538058b832c82d0cb2a02c525f632774f9990152b01d02e933008a23638cc0e4c569cf3853152e4a82c9", - "0xf86e8201bd852e90edd000830186a094d29c68d31ab1c10ce900479686fe3525669f17fe87038d7ea4c68000802da0ff22f8bfd0357a045c71757da6776fe2b38bf0d9ec9a4312389e2bb8c74e7f85a0734dc43fdafaf9ce06a013f024ea089c3bf9244679bfb798a4dd625bb77bb4db", - "0x02f8b105118520d1bfab5f852a4a4c643782e4409407865c6e87b9f70255377e024ace6630c1eaa37f80b844a9059cbb00000000000000000000000027bb53e4f40f0b44db0efb23cd9d88ef6d7b15a700000000000000000000000000000000000000000000000000000000000f4240c080a03ebb4568488336818788967183440aed83f2fc3b1f21281e9caf35830987d877a02f2e727f0e24167cc564fa3ca605ae4288039441938653e0afc1d0e8f1e7e553", - "0x02f8b20581e485174876e800854586f1ac5982b67a9402cdc279823190daf56860239e5f2680a50e3d0e80b844095ea7b3000000000000000000000000affa66384d9741a6eab6d426002721784d753fac00000000000000000000000000000000000000000000000001112af15d4635c3c001a008cd6e27cfb8401465c5cf7931416ddf24fbb84be60507d287a7efb1aec98220a063c88928e3794eedcc3902bdd6ff83e99316c34c77843facd4ef03e0d8678ad7", - "0xf9024e8309c31a8513b5fc2520831180e094a658742d33ebd2ce2f0bdff73515aa797fd161d980b901e4252f7b01000000000000000000000000000000000000000000000000000000000000006e0000000000000000000000004f7a67464b5976d7547c860109e4432d50afb38e0000000000000000000000000000000000000000000000000000000000030d40863f9169c3463fd8ec29548c1bba1acd37b550f53c48736f6e9b6d9f68c01f38863f9169c3463fd8ec29548c1bba1acd37b550f53c48736f6e9b6d9f68c01f3800000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000f40000000000000000000000004d73adb72bc3dd368966edd0f0b2148401a178e200000000000796ef006edd69db25f6d620a7bad3023c5d32761d353d3de9009a4f7a67464b5976d7547c860109e4432d50afb38e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000003bc991e9ee6a75f0000000000000000000000000000000000000000000000000000000000000014ee37567502d838e991dddc667f39bbfe0fc00afe0000000000000000000000000000000000000000000000002da0354b553325f76f371511523d3c07145b565af927bb0760f0e5cb45f4425a079ea035a2315e3360045723738eba65fb4163da66583a7e12e62dc1a7814f70b2b669", - "0xf86e83026e4b850deae7ffd182f61894bcd18f337f5a0cc819205004ff8bd05df282794c87470de4df820000802ea0c85c68ec90f6384cf92bd3523f66797e6b588a68013a269f646859f66c19a121a020611a2cba73bf6eb4a461496d7dc054f40f35aa758cdb9398926db9feb83ee4", - "0xf86e8304bdf0850deae7ffd182f618940739e9816ef6bad34fb9251706030c1c896ebd7287470de4df820000802ea0c4af6cd7e903f5b4982213585fc2e7fee46dec5a2f3d5051bce90f999c4935efa06eeb0d85ac2339eed6059468d043db89ca1f52ba66e83a845432bc76f509b5db", - "0xf86e83026e7a850deae7ffd182f61894f66266e6da69b2d5b454bddfc4fd03ec8474ac7087470de4df820000802ea053a312403d355028e1dfb8ef09bfc8321ec50d6ccc5cf8f0d41c5ad96f2d7363a03a7880ab997550b00e17fe4323f944255fd83b749be0cd28ccfd852a06076a73", - "0xf9024e8309c31b850b8b378a86831180e094a658742d33ebd2ce2f0bdff73515aa797fd161d980b901e4252f7b01000000000000000000000000000000000000000000000000000000000000006e0000000000000000000000004f7a67464b5976d7547c860109e4432d50afb38e0000000000000000000000000000000000000000000000000000000000030d4099453f564709b2da67bcc92f88376fa86e7a75b4a3bda1832383d2f2d9cbf17499453f564709b2da67bcc92f88376fa86e7a75b4a3bda1832383d2f2d9cbf17400000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000f40000000000000000000000004d73adb72bc3dd368966edd0f0b2148401a178e200000000000796f0006edd69db25f6d620a7bad3023c5d32761d353d3de9009a4f7a67464b5976d7547c860109e4432d50afb38e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000005245165295880ef000000000000000000000000000000000000000000000000000000000000001473b43834edf330b368b1de12389f3788a829d16d0000000000000000000000000000000000000000000000002da00bc3cd259e25a1f98522211a6e8e1d9509a5c3f7c470a6fa1cee5cfc7cc7224ea052942e2fb85b032e7d97cd53936d9667757165af2b1bbcbb94cda704065e47c7", - "0xf9024e8309c31c850b8b378a86831180e094a658742d33ebd2ce2f0bdff73515aa797fd161d980b901e4252f7b01000000000000000000000000000000000000000000000000000000000000006e0000000000000000000000004f7a67464b5976d7547c860109e4432d50afb38e0000000000000000000000000000000000000000000000000000000000030d40f5dc15dc0ddd284f0e1ed59df3a3de806ca0771a76524880088ea04398a621d0f5dc15dc0ddd284f0e1ed59df3a3de806ca0771a76524880088ea04398a621d000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000f40000000000000000000000004d73adb72bc3dd368966edd0f0b2148401a178e200000000000796f1006edd69db25f6d620a7bad3023c5d32761d353d3de9009a4f7a67464b5976d7547c860109e4432d50afb38e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000020ec54c4a1aa15bf00000000000000000000000000000000000000000000000000000000000000014fde6167c97e3523bd7672a348047b001a593e4350000000000000000000000000000000000000000000000002da0ca39bd5d52f9ee658dae4acb770db889a839e6fcd8fdc6f797d4e699462eeebea02d00594f1323677f846681461d85b8b36f3daeaafd8c10c53583086dce66c472", - "0xf9026e83017571850b8b378a8683048d9c94a6bf2be6c60175601bf88217c75dd4b14abb5fbb80b902046c459a28000000000000000000000000980205d352f198748b626f6f7c38a8a5663ec9810000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000006452aab000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000084704316e5000000000000000000000000000000000000000000000000000000000000006ef6fc95fe31194fc82c102ffbbf55d2f65e4f41cb100546db65e51a137a3a644f0000000000000000000000000000000000000000000000000000000000000014f6fc95fe31194fc82c102ffbbf55d2f65e4f41cb100546db65e51a137a3a644f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008281e0cdb9452df678fbdd337a2311be54d41bf69f18cea485f15e96fce7c3e5ab52f21b04e413046ab8aba282a10f91b09a30b8aa06818c8b3310d1eaf76a69591b1ff6372b6fc697fd08a886b126d62cbe27bbd090e2010f4044420b166e0b665e4c0feb3821cd5fb07c2c8059bd270e89a07c6b3dc8e87ee2d827090a16002ad31b0000000000000000000000000000000000000000000000000000000000002ea00fdb0a2ea5a9904a643b0bc868baa34606efe734e97dadbb55f1dd730f11be5ca03335ccc416a1c36baae8417e04d70365e7cedf4de6149241f8e26c246ffe6b88", - "0xf86f83027ea785094745553682520894e12c2c16f7f0e24a9c9d7ef09cd21afa1d11662188016345785d8a0000802ea0cbe7cdb56062c288711917889636a86449681ee48731df4c3be9aed130d31afda01998c983a185cbcbd773f49f67f3dff7bf117c6ad9772dd4c5614cbd519a9848", - "0xf86f831201e5850904d9693b825208945a0f6db1d257394d73d6f78ac7efd82de25207b888097cb99ba2e939a2802da0a894003e9129435956393d70a4ea802bc9a04f09578af3c84fb7f327740f8fbda057cec134e9fce157efefa7ab84487e4dc37e060bf4bc7f8a1f095b43fc9f658f", - "0xf86e831201e6850904d9693b82520894e3ea6d134349abf964f8f6e53ed7965218da1722879f33c341fb3908802ea0aac6713a1ec92812582251b4e2739cbd5df7455a4a269bc540356af0fa36ceaea05e16aa15d446d86102b9383ea59db5e24f7957a122aa73a1106106b435d204d3", - "0xf86f831201e7850787079ec082520894dd447f0cde89528824086895366c08679890c0b48801189ca0983f4a4d802ea0b6677ff3311a54883020840c35064eb8250b1deb095d594a64d00be7d98bca03a032330a1c22a86098737a861584315c4f627d87343e0116c451a25027469ee07d", - "0xf86e831201e8850a02c8703c82520894803868f83846199c70dd14b2be8beef86c3a50c4879f6255c2afb88c802da0da1ec99f36681006a328e7cf860d5e665a2dbe8e4fcf2461fae876f0d2b0671fa022499bd6eb18cb32796f8be7802ce3110109e2d4b6c3f2520a70cfb97e8f17a2", - "0x02f8770582073085067c95dd0085067c95dd0083033450944e0ba4e96813fea31c538efd015ac6646205da0a8803311fc80a57000080c001a0afd0a0f8ef968e09d624e4507ca8b53c308a9ec3315129eedd3cfbe0beeffdaea06f85a9a99bfc1dd3fef15e4dd42dff570beabe6e464fc6c52f7c3af6f896b43f", - "0x02f8ba0580850676584d72850676584d72830451f794e5e30e7c24e4dfcb281a682562e53154c15d33328801f7533714cac640b8449f8420b300000000000000000000000000000000000000000000000001f7532dc49b36400000000000000000000000000000000000000000000000000000000000009c40c001a0f82440a4555ea34292c330b42c07f8e94a6ff0dcee38581e44e5811eb9b7ee57a01744aea86365a26a35d53a5c4aff6fc494709d1e3d1a39113a19af9e9df21e63", - "0xf9012c8288b485059682f0008302e4b094c92470d7ffa21473611ab6c6e2fcfb8637c8f33080b8c458a997f60000000000000000000000005a94dc6cc85fda49d8e9a8b85dde8629025c42be000000000000000000000000deaddeaddeaddeaddeaddeaddeaddeaddead000000000000000000000000000000000000000000000000003635c9adc5dea000000000000000000000000000000000000000000000000000000000000000030d4000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000002ea07a10e69b3420a93177c94b31adc98782b25c48b6c58ca1b4f363d1222e5c085ba0772341cb648c66cfd34b7c01ea3bac96dedf1c02db62d6eac85086d14c48d948", - "0x02f8740580850573da8158850573da81588252089472f75c5c5754854790ac144ca0fe2d68ddafde36880f390034bc41454080c080a0f68a3bc319049e0f300b41528aa04d509818d82bfbefc11506fcd20f2100fa2ba0529840e6428824e1b738040001be19107a6973cd0eeb81d84c78adbf8191b3c7", - "0x02f8b30583014177849502f9008509d05c8c3682cc93945a94dc6cc85fda49d8e9a8b85dde8629025c42be80b844a9059cbb000000000000000000000000adf8b0883aba74232f26462d71fd54663b4d9fda00000000000000000000000000000000000000000000003635c9adc5dea00000c080a0a22a9c36768fa467f61a75d2d909725fb4c20c2c0022a6b4a589438ff4ae4ebca052dee5948a087a0476269eca17e31617b45584859c2e33cd28bf73a8035bb63b", - "0x02f8d30582019c84773594008508a927c5cb83010d72949c33d07e36fe6acedaadbdf30029b75531f62cc480b86423ff31a200000000000000000000000000000000000000000000000000121e6c485ac00000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000c001a0765a466be98729daf8e35765b81d2753c7a85120ea6a9812ed8164f138200be6a038aba37506bd7fb81fdc3e31872a7dcd94294e3d7b256e42c6ac7495f692f887", - "0x02f9015a0582013584773594008508a927c5cb830f4240949051dc48d27dab53dbab9e844f8e48c469603938872386f26fc10000b8e4deace8f5000000000000000000000000000000000000000000000000000000000000e704000000000000000000000000d436517fd3e2b7fbb0b234e4ee34f81dc1cf21a100000000000000000000000000000000000000000000002b5e3af16b1880000000000000000000000000000000000000000000000000002b26b8169c7af0000000000000000000000000000000000000000000000000000000000000645bcd43000000000000000000000000b47de784ab8702ec35c5eab225d6f6ce476ddd280000000000000000000000000000000000000000000000000000000000000000c001a0396e0f5e264ccbd579ef1e6e58929ba4b2b12931bef44d535188095f00188a12a015b5af32d3f6b4a198e741c0513ae8494348d0aedbc329c61ea076579aa81043", - "0x02f8750583107c83847735940085746a528800825208947a0fb632f86a8c8236ac8960b3a9cada3e7e0b30874c39bfa5033f0080c001a060a50ed1e2a9a4ab76be8747aec4d7320a236a148895ca11ad3e714093b1e0b8a009a62f99a6c4539d2426ee95177cf393ac34a5136e75e4adb58af86f685332d3", - "0x02f8760583107c84847735940085746a5288008252089473efc5030451e34c409df5f536a8636f4f8027588801c836f8e4e4100080c080a063addc95d1083ec4fac8b611276fc5de75ec8dd278f2aacd23541b4aec20cdc7a03b3d306f98f9cbdc4b908e8d741e566f9a95d004b2657533849690198f5006a4", - "0x02f8bb0583016c7784773594008505b6423270830289a89498aa442cefcaf0a7277d10889d07d04e90b37ea587038d7ea4c68000b84458891a3700000000000000000000000071383ff4de8b1b1da845c1e3fe40f03c054172fe0000000000000000000000000000000000000000000000000000000000000001c001a071c594533cc47af2cbeeb417896957de8b16ba690133eca554eb68100a6990b4a02f3a9e4be81fb19dd6e11efc36a0307cd8bf71a66b18aad58f41d7134f05eab7", - "0x02f9013105808477359400850650284c588301062694c80b3f9ce077749c43f945ab3fc6ec78c02ed4d180b8c4f242432a0000000000000000000000009735e6aeae7c78bb7f0f917ba2b086df12c0193c000000000000000000000000f0b443f0f6b8d01d3ae8a645af440c32ef3e61830000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c001a033f73bfae88b4c70f3a1d7b55c40614f878cfdb574ecc7eb1f2d0231131aa11ea0502a19dfc5144f31c47a16ab17217903974d0c1eb7f64299ea820c83f1191a05", - "0x02f8bb0583016c7884773594008505b6423270830289a89498aa442cefcaf0a7277d10889d07d04e90b37ea587038d7ea4c68000b84458891a37000000000000000000000000a2747d51e2b2b184644ae9809f7bcf162b4033e00000000000000000000000000000000000000000000000000000000000000001c001a0a99cb5469dfe2ecc9732e6eaeb98a2094502652b06f5f6802b4ae7f8e3f278afa04f9d5052e482d5f190cefd84dd1c494bc79eef3d0d3da7b0dc05eac6108d7e9c", - "0x02f8750583107c85847735940085746a52880082520894cd26f2f818b68ddf2d100ad916a7ca399ae69c85879078ce473b500080c001a0f1de870376b9668d21e5be9d8429cb007c8b3b9dd81257bd2ae7ff87e26c7681a020320692ac7c9f52c9cb84243d1b2ba2e60c51b7ffd75b24e87a957465fb03ee", - "0x02f9021905808477359400850628f9296c83039fa19458600af7c48b4f00b0280b49cb93086961f93de787071afd498d0000b901a484bb1e420000000000000000000000007266db7f988e2516063d0b7b85258f5e6b4019b40000000000000000000000000000000000000000000000000000000000000002000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000080ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000038d7ea4c68000000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a0ebe9546e67954fa446559645f9096f3a1f3395231b46a4a1ad48406ab03f9b3ca0347701a76959b057ff73bca4243606c59df7ba01727691bf30a30f5fd5004b04", - "0x02f8b9058202828459682f008506db6c477c82d57a9441e5e6045f91b61aacc99edca0967d518fb44cfb875df822864d68e3b84440c10f19000000000000000000000000c1bcbe74305a789873e983ac10a7e8452796b1260000000000000000000000000000000000000000000000008ac7230489e80000c080a01d83dddce075c9449a16425f3a853cfc67591f9fe2993826e306a6a1b116364fa05634587404125ff74cdfb7baf5e98c426c6ba621f01678a7601ab30669a178dc", - "0x02f8b20582015e8459682f008506db6c477c8255b894c02aaa39b223fe8d0a0e5c4f27ead9083c756cc280b844095ea7b3000000000000000000000000a86a38ad92035884396df4e8a6cf5eca75948493ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080a06225cc16f067c9b93b06ca8cbebe28775ba5f730c1158fc5f3fa6b3b3b60f0dea03dda7ad71554cfa91667fb690b7fefcd1901f548b66bd83ef1b7a7babedb9e3d", - "0x02f8b705748459682f008506db6c477c82d57a9438af6928bf1fd6b3c768752e716c49eb8206e20c87470de4df820000b84440c10f190000000000000000000000009b8442af540a642b5eba32d0f0ce0e9c0026283900000000000000000000000000000000000000000000000ad78ebc5ac6200000c080a00c7cc52393e38c044b369529cd58187b7675408718b6d3e8ddc52173ced60793a03628146aa7d6acb722d0b661567603c7c41d29603ad70697748ceae84ea21695", - "0x02f8b0050d8459682f008506db6c477c82b88d9438af6928bf1fd6b3c768752e716c49eb8206e20c80b844095ea7b30000000000000000000000009051dc48d27dab53dbab9e844f8e48c469603938ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080a06c6742f0250e1b184c2d850fe8684ba3b6bfb7a06d9d1d372d5682c77ab06defa02eb6a4b797de6cfb6345382d010aed46573073e4c820da4240864fcfd66f9726", - "0x02f8740581938459682f008506db6c477c82520894111a58a62c94272a9a5ab976de8fbc4bf7e8e6ad880de0b6b3a764000080c001a0a4adf81f3407a81b555f0c22b9e75d6d5437e9adad93cbb8f2b74b68c8da732ea00cb53a10d3e30da33897572dbb0911447b70d63ff20591ae93a6bd2b5902fbfc", - "0x02f8b1053d8459682f008506db6c477c830f42409438af6928bf1fd6b3c768752e716c49eb8206e20c80b844095ea7b30000000000000000000000009051dc48d27dab53dbab9e844f8e48c46960393800000000000000000000000000000000000000000000000ad78ebc5ac6200000c001a0e09aa04652fc52777bc5644439413753488440ef32d4e250f293b0d2919148ffa0374a90a5920598a6df34e99ca46d73d4416a33ddc99f8f517bc2ad882875e23c", - "0x02f8710581858459682f008506db6c477c8306957d9480fa9d2fe58b1254512ddd0ed1c07acc77ff5fe480841249c58bc001a0813e8a719ed801dbed69f258c4e9fe3c26fade4e04f74c82ac3615879b19aac7a0405b8ad7b28eb9d117127aaad89eb433d8b6b3364bcd30de2ad092dcd7c78011", - "0x02f8b705118459682f00850708346f6582d5869438af6928bf1fd6b3c768752e716c49eb8206e20c872386f26fc10000b84440c10f190000000000000000000000000cf3263d9c73c2dc762c1e07769a7e064c23d7650000000000000000000000000000000000000000000000056bc75e2d63100000c001a0b62dd0592e017f97c0e40f5f77b3f2be343e4d167f7f7a2dfa9fc49a7e5bbd76a0633a2ca068c0d2d96b75d45fc91a3accf3d45d171b5cc62eb32e90ae58aa855b", - "0x02f90158050d8459682f008506db6c477c830f424094889cd829ce211c92b31fdfe1d75299482839ea2b872386f26fc10000b8e4deace8f5000000000000000000000000000000000000000000000000000000000000e704000000000000000000000000e8a2d13d070b10b60d4e048583b887882b95bac500000000000000000000000000000000000000000000000000000000002625a0000000000000000000000000000000000000000000000000000000000000029500000000000000000000000000000000000000000000000000000000645bd6c8000000000000000000000000b47de784ab8702ec35c5eab225d6f6ce476ddd280000000000000000000000000000000000000000000000000000000000000000c001a02489664a24c8a792ca256f42c08ae6a38fee29483c58ea4bb8ac00234c7a2435a031b311cca5327c831b608d3a7a791e6ba9e80e45b2e0bc3e15a72387f6eba5ba", - "0x02f873051e8459682f008506db6c477c8252089410ad76b7f1c984593fc62b0f60882e533eb0dc1c88016345785d8a000080c001a05ad5a53c67721e244f2c5cd958c690efb348948d8153b3e465131768e826dad8a06c238584ce8aa9414468f608fb584bea9cf59935a258d41e183e96bbbbca6ec1", - "0x02f8b005148459682f00850708346f6582b4989480fa9d2fe58b1254512ddd0ed1c07acc77ff5fe480b844a22cb4650000000000000000000000009c33d07e36fe6acedaadbdf30029b75531f62cc40000000000000000000000000000000000000000000000000000000000000001c080a0ea4893969c9f5cfcdb3b3305c3b9af6cdb138b786973aaeb8562989f59533241a030c1352600f7f0882709dae400b940fda18a6800fc609a429892a6646bed04ff", - "0x02f902fa05338459682f008506db6c477c830358ea944648a43b2c14da09fdf82b161150d3f634f4049188016345785d8a0000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000006452a39c00000000000000000000000000000000000000000000000000000000000000020b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000020688f00d1c0dc4b79284343e00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002bb4fbf271143f4fbf7b91a5ded31805e42b2208d6002710dc31ee1784292379fbb2964b3b9c4124d8f89c60000000000000000000000000000000000000000000c001a0e19cf8cca7e65ceee15a7da899ee79b78f34f585d2f56cc470ee3cb575b1bff5a03f65fac2014f13e5922eb0c72464c83daaf440c776898ee6cdd42377f686a9ec", - "0x02f90159051e8459682f008506db6c477c830f424094d9e10c6b1bd26de4e2749ce8afe8dd64294bcbf58845871874b4b50000b8e4deace8f5000000000000000000000000000000000000000000000000000000000000e704000000000000000000000000fd3df177e50fe9540ce6cdfbc69a38604916a71d0000000000000000000000000000000000000000000000004563918244f4000000000000000000000000000000000000000000000000000044c9a9b85e72a4c600000000000000000000000000000000000000000000000000000000645bd6d100000000000000000000000081682250d4566b2986a2b33e23e7c52d401b7ab7000000000000000000000000000000000000000000000000002386f26fc10000c080a09c9b069187c56ed0f408d0fc30e26a4ee7834fec11658391ba41c3885ebdb452a07cc1c21cc89cc4a3888428c1e1a2f28901cb5bbcc4eae08539d7d03bd8e022d4", - "0x02f8b1052b8459682f008506db6c477c830f42409407865c6e87b9f70255377e024ace6630c1eaa37f80b844095ea7b3000000000000000000000000889cd829ce211c92b31fdfe1d75299482839ea2b0000000000000000000000000000000000000000000000000000000000989680c080a023bd490a5e701d64b23fa5ac72dd141d1129738cbec17a63f996a7684236aca7a01b7542ff9a0740476860ce539132450a0e202d7a1f01e37d39796b16d20a0eef", - "0x02f87205088459682f008506db6c477c825208948134643edb2fcbefacbde28f38e3d3b6e655240c88016345785d8a000080c001a0687c53a0c75d776e984d170fea68daf39c48bf461839415d01d2eee5decc0aea9fd676b0d58f35fbe02937d476614034a205df129cf8695a8aca2b113fa4a46c", - "0x02f8b005198459682f008506db6c477c82eb929407865c6e87b9f70255377e024ace6630c1eaa37f80b844095ea7b3000000000000000000000000889cd829ce211c92b31fdfe1d75299482839ea2b00000000000000000000000000000000000000000000000000000002540be400c080a0cb1693afc742c4e80cd335e04521ea99be49c33f228d55a0fdfef27b54a606e2a05561cff9a1d3dae67a1fb4fb4365ec5959ed0727042bbbb4204a1e4f34f19a3e", - "0x02f8b0050d8459682f008506db6c477c82b76194b93cba7013f4557cdfb590fd152d24ef4063485f80b844095ea7b3000000000000000000000000aa1603822b43e592e33b58d34b4423e1bcd8b4dc000000000000000000000000000000000000000000000001158e460913d00000c080a081148a1dde069df9dfb9ba3873256285a4ad47fff36e5bd2e31c03b053332f17a02a488e237c9fc91a0ab9f31cc65891e0a87201624463d5f5aa05a3b7c9b11b19", - "0x02f87405823a428459682f00850994c1c23682520894dab1a1854214684ace522439684a145e6250523387017dfcdece400080c001a03d474b1b610977f36a314b39e85da53f575a4976d4fbab1dd293df301e3baea1a03502ed39bae3890065f538f02ab1fc9ac383c3418a5fe7f70c23cb2e52d44775", - "0x02f901d2052d8459682f008506db6c477c83104bc1943225d9e0ffecb7f5ddf8efa568e250f90b91c27780b90164f2c78a5600000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004c4000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000068155a43676e0000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000326c080a093fee0d28d41590fea661cd1c16bd784d09320a38d95b70476c8063f5c83e849a04dd92bc2f4bc5c6b6d69c4985d263aeb1652e05cf0430eadd75135f9a6399a3b", - "0x02f8b805028459682f008506db6c477c8304521394e5e30e7c24e4dfcb281a682562e53154c15d3332872386fbbff09000b8449f8420b3000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000009c40c001a00a8ea9d65b57273bb2c30179b8de532c39140b867a9bd4a683e779cfdbcdcd57a04a38f5cdde8330d332e1aa43306ffa7ac5b7673d69be16812cc475f2b2de6d2a", - "0x02f8b005118459682f008506db6c477c82eb869407865c6e87b9f70255377e024ace6630c1eaa37f80b844095ea7b3000000000000000000000000889cd829ce211c92b31fdfe1d75299482839ea2b00000000000000000000000000000000000000000000000000000000003567e0c080a0cc160d3fba8e22961e288d1bdd994e9b3a0643e702dcd45d1f88b0ae73471167a009356e1e04a7a01ca00a7e91324a528f9d3c796c390ec97b08f8041ede2716a4", - "0x02f8f9057b8459682f008506db6c477c830270b4949c33d07e36fe6acedaadbdf30029b75531f62cc488015956cac01f44d9b884c5bb31680000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000015956cac01f44d90000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000271dc080a09595f9e78d4d1128a116ecafa5d2ff428da4c93c726f8164ea0b7854d45cab7ba013133498b69ef55b4f8b4a4a797fcd7a2b3fbb702d57b6d2e8c26d5a8f97be27", - "0x02f8b005218459682f008506db6c477c82b4cb941d8a8f8a0208f908974060eef0cc4e6a79d94f7d80b844095ea7b3000000000000000000000000cc9f513304317c0688bcf572cba35dbaa84f9c1e0000000000000000000000000000000000000000000000008ac7230489e80000c001a0098edc5cb61e061b57603bbdf8b2c0c18baca6a3d437c6741d5a56082f4e6764a06e6c2221d559188aeafaaf86e17a4746584f372ade9670b12e7e92dffe59a3fd", - "0x02f8710581868459682f008506db6c477c8306a1bf9432e724c4d163aebcefe707fc9ba8cf7db65caab880841249c58bc080a01db502881214d73ed072f6304fa472be3d5702b7a36fb49c3079518e06948346a0565d5bdd13255c52c8943aa20ce5b21009c5aafbff252f27e33e4282f078398b", - "0x02f8af05428459682f008506db6c477c82b73a945995d54a4bd0b79c4164086d24c70c3807cfeff980b844095ea7b3000000000000000000000000302fd86163cb9ad5533b3952dafa3b633a82bc510000000000000000000000000000000000000000000000056bc75e2d63100000c080a021827a199ae559b79e139fa772c5731a90cd87fda9b666f09e1240ffb71f09f79fdb707fe524434dd484cac7eeb616996ac4a3ea7939b38994908389e7510f9c", - "0x02f902fa050a8459682f008506db6c477c830357a3944648a43b2c14da09fdf82b161150d3f634f404918802c68af0bb140000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000006452a37800000000000000000000000000000000000000000000000000000000000000020b080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000002c68af0bb1400000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000002c68af0bb14000000000000000000000000000000000000000000000000000007177137c5d34f3100000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000002cdc279823190daf56860239e5f2680a50e3d0ec001a07c692da1f89ecfd7713d3a249d01ad14ada9ff2ca63effa27a7823537a25a934a0532f1325cf0b42bb0b7a9c0f3dc950496a864bf21cdf81478bd7275a70563276", - "0x02f9019a050e8459682f00850730c4bce4830246da941908e2bf4a88f91e4ef0dc72f02b8ea36bea2319880508314a13a34b23b90124eb672419000000000000000000000000359477a7fb0ec693c0efe6a810d94c60185921ad00000000000000000000000000000000000000000000000005068e5cb5d6ee2700000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000ab5b400000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000359477a7fb0ec693c0efe6a810d94c60185921ad00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a06821f32ed809e5215775e451bec35a13dad74f74a7ad3cb73decf617268c31fba042dd4544ff49f13b24f4adc74bf17db56a64822688b3cce701a321fc433af866", - "0x02f8d1052a8459682f00850708346f6583031812947f33ca8ff46d7dbb0aa650bef24175367e3d831780b86437e8a147000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000013f306a2409fc0000c001a0a67c358f41a73a66aaa8fa375389a632f864a14f713c5af0380011ff14577d97a04e64fc2e6fa3159356fce48f69e03cd759c780a04d313912a19b0357d4959ff7", - "0x02f90377058201278459682f00850681a1e1e88303a3f9944648a43b2c14da09fdf82b161150d3f634f40491835d8275b903043593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000006452a39c00000000000000000000000000000000000000000000000000000000000000030b010c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000005d8275000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000005d827500000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002bdc31ee1784292379fbb2964b3b9c4124d8f89c600001f4b4fbf271143f4fbf7b91a5ded31805e42b2208d6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000c080a093ee3afe5665ed05a762419ad4f345fc0dc40f79f76db869c1f456ca820f6f45a07e5a99a96f8c6d96ec3ad2dea9e4909f2d25c008a7a568105079193365ac52d1", - "0x02f8b705018459682f008506db6c477c82d58694b93cba7013f4557cdfb590fd152d24ef4063485f87b1a2bc2ec50000b84440c10f1900000000000000000000000016b5d21c55c9b8c5d19a61c3fc84bab298487f9e0000000000000000000000000000000000000000000000056bc75e2d63100000c001a04dd1bf5af9dcfd34115102f45118a6a6404623ca385693aa2ae2015bc7a6333fa049cd2c6680ce68636ad72673a98deae6c334241d96eb078213a22f9b28ab7be4", - "0x02f8b8050a8459682f008506db6c477c82d5869438af6928bf1fd6b3c768752e716c49eb8206e20c88016345785d8a0000b84440c10f19000000000000000000000000a921890db440b6ea9f77b3ca5112e8ee39dc9cb800000000000000000000000000000000000000000000003635c9adc5dea00000c001a0d00326bd29a4fe224a722169799f2f0e563f33e2d45d3951290ff85d9749b8d1a042bc1a0e4a804b2a5bbbcd217d4a0654fd494709220ac84d843d79034619c6db", - "0x02f9015805128459682f00850708346f65830f4240949051dc48d27dab53dbab9e844f8e48c469603938872386f26fc10000b8e4deace8f5000000000000000000000000000000000000000000000000000000000000e704000000000000000000000000f444c6e86d026ece075068c859e4c91223e4901f00000000000000000000000000000000000000000000001b1ae4d6e2ef50000000000000000000000000000000000000000000000000001af8330e21ccd6000000000000000000000000000000000000000000000000000000000000645bd6a5000000000000000000000000b47de784ab8702ec35c5eab225d6f6ce476ddd280000000000000000000000000000000000000000000000000000000000000000c080a08c3e0da7c2eda89afa71eccbaa3f85f9c111053957f9369cb5b195eb2d2d9b0aa03e901d5f9d762aff9667cfc7ca77b06fdfc4f97fa0d8826f58a5a87390241060", - "0x02f8b0051c8459682f00850708346f6582b76194b93cba7013f4557cdfb590fd152d24ef4063485f80b844095ea7b3000000000000000000000000aa1603822b43e592e33b58d34b4423e1bcd8b4dc000000000000000000000000000000000000000000000001158e460913d00000c080a01587bcfc475e453f0c6947d98ce55aaa89d4635b726841207239874a8ec0a658a03eea6b96ce25510d0c72c00fef981e30abd3c93bb136745850e555a489e2cc81", - "0x02f87305808459682f00852e90edd00082520894fd6140999ca02a0ee7b75856009c6f219627892c880dd1cad2f355800080c080a0e810344b0f578a0fd6373209cc6b37d5424ca9905c45fc67b3ac74c48560bce7a0555d7b80b69fca438078567a373fa87d9c829c94586e995bf364a9711604174d", - "0x02f9017b0581858459682f00850681a1e1e883061a8094805fe47d1fe7d86496753bb4b36206953c1ae66088016345785d8a0000b9010485ff842c00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000080383847bd75f91c168269aa74004877592f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000557300000000000000000000000000000000000000000000000000000000000000014a91e492b00c00b6a05186e85754133d2790ea009000000000000000000000000c001a05fb9cb803bd15acd3c8c3a79bdc3dea9c7597a60436134e60eff5ecd0424a4c6a0431d678c7f5d9b3f842b2bc42f75dd12c3f59ee2ca488910697a1c882db7e4f4", - "0x02f8d20581e48459682f008506db6c477c8303837f94779d1b5315df083e3f9e94cb495983500ba8e90780b864e7a050aa000000000000000000000000b613e78e2068d7489bb66419fb1cfa11275d14da0000000000000000000000001643e812ae58766192cf7d2cf9567df2c37e9b7f0000000000000000000000000000000000000000000000004563918244f40000c080a07e17122998ee3bc4c9a9003fc4ed855dc6939e352e1f87f84e930063662025b3a034825f83814642d191e123f66f8bf32d2216e31376112737bcc728425ad88724", - "0x02f9017b05818b8459682f008506db6c477c83061a8094805fe47d1fe7d86496753bb4b36206953c1ae66088016345785d8a0000b9010485ff842c00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000080383847bd75f91c168269aa74004877592f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061000000000000000000000000000000000000000000000000000000000005573000000000000000000000000000000000000000000000000000000000000000143149e634d632adb3cf9eb12a04178256197c6f87000000000000000000000000c001a0d55714e6663daf999667ec7711f20c4df0507fe53525f1f27d237c29788b5e95a01c1f4b071fb2643b31091b5a440a1a9979d65e125ea9a2e53b192100029d254e", - "0x02f8d905658459682f00850681a1e1e8830235b8947e639163e1a98685c88cba719c9456087922af39880de0b6b3a7640000b864b1a1a8820000000000000000000000000000000000000000000000000000000000030d4000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000c080a0824ab32af5f3f1358a9ceff87a44c97e3a4e403effdc18ee04f1e697bd108c41a053c9ca6f210094075d3ab6fbd7d69dbbcf8232ffb853af143bbeefdda9034cf1", - "0x02f8b905058459682f008506db6c477c8304520a94e5e30e7c24e4dfcb281a682562e53154c15d33328801634581adb99000b8449f8420b3000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000000000000009c40c080a0e019468d950874d4ad9b463d7eb4a401b201afe6e607477aad542cdebe7b69dda00ca8b0fb0dc025776da4cf0e68d4900b0fec6c40412e9dd729014215cd5c4899", - "0x02f87305218459682f008506db6c477c830207ed941643e812ae58766192cf7d2cf9567df2c37e9b7f87470de4df82000080c001a04533f11e0ad971fa4de8f166c7d91e815a4c4c5fd36d94e0e73fbec8d7234447a01dd047339663cfb15041a3350a9a3a73e388274917159f835ba9f8cfc66249a2", - "0x02f87305018459682f00850681a1e1e8825208946691e9ba7993a588fa007b4afe494367e87d75448802acdd0e5b2a36e180c080a0aed983a6f7ec44f1b982d61f1ecb0a79fae0c40701ae23246df7933cdb1af65fa05e5a0348d5277d473d4c10e84caf5f152ffad6009933626a43cfdfee7af8a3ac", - "0x02f87305808459682f00852e90edd00082520894ba5ba44f02f30502f50c0acc0ec394fbea606c5a880f084ca934b4000080c001a03df56496bdb85d24243f5ca947aea07e7cc70b10ad3169b74552da9f2e8ea8a8a06a86b08ec4f4b258d30dd553291a5ab9306d6f9a9c6791de55844d02cc43aca7", - "0x02f8b2058201278459682f008506db6c477c82b76194b93cba7013f4557cdfb590fd152d24ef4063485f80b844095ea7b3000000000000000000000000aa1603822b43e592e33b58d34b4423e1bcd8b4dc000000000000000000000000000000000000000000000001158e460913d00000c001a087b4f769eb229f070890638cea9271b76c2fcdf1388d56deb22d9e03e8db5968a0382222a283078774f2fad7b84c85d4baf3209ef9dae228e0135f21ce87e3778a", - "0x02f8d105158459682f00850681a1e1e883028e9694779d1b5315df083e3f9e94cb495983500ba8e90780b864e7a050aa000000000000000000000000b613e78e2068d7489bb66419fb1cfa11275d14da0000000000000000000000001643e812ae58766192cf7d2cf9567df2c37e9b7f00000000000000000000000000000000000000000000000010a741a462780001c080a0f0e3cc799d3bb9da78972f3b7f73daa1f332e787dd7c6570e7e615cdd9c67944a037846851877549bd21b5a2478f365c8299fb81c20aff97e92a8e00d61b75aa42", - "0x02f8b005198459682f008506db6c477c82b88d94b93cba7013f4557cdfb590fd152d24ef4063485f80b844095ea7b3000000000000000000000000aa1603822b43e592e33b58d34b4423e1bcd8b4dcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc080a0528cff0c28a944d58b911d49ee8cb816744adaac559c76bfdf545190fcc6ae11a011d4c5a42cacb1c2722c3566901f09a2c473a19507bc61ad0d455c38360732ab", - "0x02f8b905018459682f008506db6c477c8304520a94e5e30e7c24e4dfcb281a682562e53154c15d333288027f7d152bc19000b8449f8420b3000000000000000000000000000000000000000000000000027f7d0bdb9200000000000000000000000000000000000000000000000000000000000000009c40c080a0374352eaf857ed02eb9cb2d4a46bd834cdb40d7db6323978c8d4135e348e8a70a0175ec6659984dd453c95e4c7f41a55e34461e20eafb59577eeb143d5b83ced17", - "0x02f8b0051b8459682f00850681a1e1e882b7619438af6928bf1fd6b3c768752e716c49eb8206e20c80b844095ea7b30000000000000000000000009051dc48d27dab53dbab9e844f8e48c46960393800000000000000000000000000000000000000000000003635c9adc5dea00000c080a0665514a42625fa77d35012d7685b23a168cd2552477786b85520c929956dcfa9a03350ec27ec1dc0d58bc22224797d36eff7ebbd964574152e51d1487aa313a621", - "0x02f8b705018459682f00850681a1e1e882d57a94b93cba7013f4557cdfb590fd152d24ef4063485f87b1a2bc2ec50000b84440c10f190000000000000000000000007d16864b2171d7ed61b8af37001c8783fde95d690000000000000000000000000000000000000000000000056bc75e2d63100000c080a06a8f40db2d2f628f30efa23b3935a1ca71adaefe3994dcbcd6c463a72982d75ea03ac10ce15c8edf86fb7d7ef523df8f48e48157a820c89c9e84feb477ae1cbea4", - "0x02f9015805068459682f008506db6c477c830f4240949051dc48d27dab53dbab9e844f8e48c469603938872386f26fc10000b8e4deace8f5000000000000000000000000000000000000000000000000000000000000e7040000000000000000000000009e23345d86b1799a2617acb1b76317e32ccac96200000000000000000000000000000000000000000000001c30731cec0320000000000000000000000000000000000000000000000000001c0c5e0eb2831c000000000000000000000000000000000000000000000000000000000000645bd697000000000000000000000000b47de784ab8702ec35c5eab225d6f6ce476ddd280000000000000000000000000000000000000000000000000000000000000000c080a0142ad1e8fba0c6ced006755bc06e67153516725ff01b6cb676348d9a6b85e4efa0492faab0cc4024830a3ffaa698b0b20e9bcf9b19a4fcd5301f4c2d9e4732d88c", - "0x02f87705078459682f008506db6c477c8303edce94a9a6a14a3643690d0286574976f45abbdad8f505872386f26fc1000084d0e30db0c001a0c8e13490e357f659bf721493dfc6bf0246436fea20d7cea0613f8db9bd4220aca01b5da1bec38c1941a946997cd6f88ac7dc1bf0ac815ae5d2ff563a15e54d7537", - "0x02f8b805819d8459682f00850681a1e1e882d58694b93cba7013f4557cdfb590fd152d24ef4063485f87b1a2bc2ec50000b84440c10f1900000000000000000000000034401ee226b1fee337887a085dceb1326d85d2fa0000000000000000000000000000000000000000000000056bc75e2d63100000c001a020d417b9fb066b638bdf5a8c01a7b049fd1ae721f187aeee6870869d27b76075a017292f7a4d9d1bd1d082c65b9d0d4620c33ebf92a03d63ad061ab5dc28f30758", - "0x02f8b005068459682f00850681a1e1e882b73a9447a4357315e1d3ab3294c161c3a52e8b0d3a410980b844095ea7b3000000000000000000000000302fd86163cb9ad5533b3952dafa3b633a82bc51000000000000000000000000000000000000000000000001158e460913d00000c001a087f5be5a2f09a31f3e24881bfdbf0163651c4e85b2f5eb51f85619d677d6d456a01317e0fd5dddfd596ea09ae6c23529a7acadcc4ad2f6e4933382bc6285c3d213", - "0x02f87405829d9c8459682f00850994c1c23682520894f847a6252b6700415d2996a803002aeebd5d1ba087038d7ea4c6800080c001a044d04a2fb4e5d0465df809fe2a3acfd56b563d79dd607a1a307d12b995f75197a040cf1e56e100d34ce3ef190be4a4c5a843f05d9f36e73356eb1625c3114ae224", - "0x02f8b80581e88459682f008506db6c477c82d55694fad6367e97217cc51b4cd838cc086831f81d38c287b1a2bc2ec50000b84440c10f19000000000000000000000000fe25e9792547cc3a864fc3bc71337ed1f3f71afa0000000000000000000000000000000000000000000000000000000005f5e100c080a0a1ed59edbae7200c6d96e5991b7fdd899043b812f0164770fbe871d5a53ffbb4a019db4edd6c5ee2590f5370a91d4f411da7c7fa526b42f4663fa63372fc8349e2", - "0x02f9013105148459682f00850681a1e1e88301998994cf45a233fb21a77e67a0fc5d3e3987fa9cb59e8380b8c4e79b9db8000000000000000000000000c5bbac81754d2ccfdde030f6aea05d881752f2f8000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000e6a61636532392e746573746e6574000000000000000000000000000000000000c080a0f74c21e3ce66a4b0c6f49c6cb5f773f5ae6af006ebbb52752bfc011294ecdbcca0288a775e0899b93f8f10bf465a8819d7833b1c06766b24d2dfedf5a3a1007a77", - "0x02f8b7052b8459682f008506db6c477c82d58694b93cba7013f4557cdfb590fd152d24ef4063485f87b1a2bc2ec50000b84440c10f1900000000000000000000000097d50af0e83488ce3d595267cd95525b3aada9f10000000000000000000000000000000000000000000000056bc75e2d63100000c080a0a5a46dd0b6ef4a14cdebf9832f093f8802cdfcba65e021c278674a6250bc86d7a042fea4394989a820339a6d1549b3ece4c4a3c4a3ea75a3243bf7bb1cdc9b25e7", - "0x02f8b005318459682f00850681a1e1e882b4a49480fa9d2fe58b1254512ddd0ed1c07acc77ff5fe480b844a22cb465000000000000000000000000fcf56865e9ec7155e756d69d2d8d1e2f5ce89f860000000000000000000000000000000000000000000000000000000000000001c001a074ade40511311ec0d4f298518556f24c27dbe21e3b770fe63cd569db6246fbf2a045bdd63a468f090dde0c8a381b15f85f3d24b8be0dc3309948a42d271dcf58d9", - "0x02f9019905148459682f008507d2c286af830246da941908e2bf4a88f91e4ef0dc72f02b8ea36bea23198748f01c0c428f23b90124eb672419000000000000000000000000c47b195587fa6c50306abc5ebab29c255d7f8a8100000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000b54a300000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000c47b195587fa6c50306abc5ebab29c255d7f8a8100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a050e1ee5b43197b8a26d7fbb90c1026c0dd15b5d651e8dea447d9522dcfe72e90a0387817200f3ce84e00aecbb0ca6529b81c39dce36e355e3ee9ea379e8d085099", - "0x02f9045a05158459682f00850681a1e1e88306243d944648a43b2c14da09fdf82b161150d3f634f4049188016345785d8a0000b903e43593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000006452a15000000000000000000000000000000000000000000000000000000000000000030b000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000016345785d8a00000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000eeec9b06d6dbf868d50f0f46a6389b9778344382000000000000000000000000000000000000000000000000016345785d8a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042b4fbf271143f4fbf7b91a5ded31805e42b2208d6000bb811fe4b6ae13d2a6055c8d9cf65c55bac32b5d8440001f4b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003dc7cd971fbf83500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d600000000000000000000000002cdc279823190daf56860239e5f2680a50e3d0ec080a0b6f1e816bfd64bea9ca2549683d6be15cfee37a927b45e9888a01db99a1c178ea0697cb263f0d4cf2bf36aad177778b6aa770f8fae522dacdb7772bbc197dadfb7", - "0x02f901590581e18459682f00850681a1e1e8830f424094d9e10c6b1bd26de4e2749ce8afe8dd64294bcbf5878e1bc9bf040000b8e4deace8f5000000000000000000000000000000000000000000000000000000000000e7040000000000000000000000001c52216e2c08b7c86f27fe74d7d6206bb0648794000000000000000000000000000000000000000000000000006a94d74f4300000000000000000000000000000000000000000000000000000046583da915ea6900000000000000000000000000000000000000000000000000000000645bd64600000000000000000000000081682250d4566b2986a2b33e23e7c52d401b7ab7000000000000000000000000000000000000000000000000002386f26fc10000c080a08ca38d97aaf6281ad1befb36b7bfdcbbad589923d7a1f023f421c13e1bbed4e0a001805871ab16d6a3a9d7e6e0d2e6e3593d6340451e22c61371baa3d660cf64fe", - "0x02f901b2054d8459682f00850681a1e1e883061a8094805fe47d1fe7d86496753bb4b36206953c1ae66080b901449848a6b3000000000000000000000000cc7bb2d219a0fc08033e130629c2b854b7ba919500000000000000000000000000000000000000000000000029a2241af62c00000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000557300000000000000000000000000000000000000000000000000000000000000014027aab1d6b13885ce2ada9a70e6cafa31271fd1d000000000000000000000000c080a0936a17994b8782e7511badc8636253e064e58bc8d7786d0924620f353c8c221ba06a971b60050f102cee127c054cf0b2a7a222744d6651131027ba46d5f15e557c", - "0x02f9017905038459682f00850681a1e1e883061a8094805fe47d1fe7d86496753bb4b36206953c1ae66087b1a2bc2ec50000b9010485ff842c00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000080383847bd75f91c168269aa74004877592f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006100000000000000000000000000000000000000000000000000000000000557300000000000000000000000000000000000000000000000000000000000000014bbaec5458f67197de96f2ca3d94d634316c804a9000000000000000000000000c080a09c3d11c59094f5f72e3fb71859533a668bd93d9969fe92beeb32e0360b2d17b2a05c14bfb1febbc9204b9e8696257999251ae4299ea661ba2d3f17af5ad3ff80c7", - "0x02f87305018459682f00850681a1e1e8825208946691e9ba7993a588fa007b4afe494367e87d7544880142e9f93b69950a80c001a0ec8fed3856af4ba519f0fa5e35c8aaa4c80ecb55254697d957c0c992b29d9387a07769ee78933c3f5faf9a1f37327a5d5637b3f67ff08e1a4ce2c37bfc362fbef4", - "0x02f8b005448459682f00850681a1e1e882b7619438af6928bf1fd6b3c768752e716c49eb8206e20c80b844095ea7b30000000000000000000000009051dc48d27dab53dbab9e844f8e48c46960393800000000000000000000000000000000000000000000003635c9adc5dea00000c080a0c4b091cd5c91856c1bf3fe5490509d3440b6eeff21df88779789237a8b90419da062c10773737d28a96670fa11fcbad7b4dcc5bf5c9b3a1402e3d2a8468a5b0327", - "0x02f8b0051d8459682f00850681a1e1e882ea1094932ca55b9ef0b3094e8fa82435b3b4c50d71304380b844a22cb4650000000000000000000000001e0049783f008a0085193e00003d00cd54003c710000000000000000000000000000000000000000000000000000000000000001c001a0a5f6e45864847b75839ad46e8b9b9422ccb861e17569901058e9c5c7830132b3a019a2532311e0ba050d73f0bc7c63056d8866dfd9f0429414e1ddd2b4d190343c", - "0x02f873053d8459682f008506db6c477c82520894f32680cb72981e94265cbdd7e0a9a510a2a13d9c8814d1120d7b16000080c080a0285f026346e63afbc0ae3bdf87bb7ad76280ef1dabc0f221863b5a0e761f7529a01a8302068397e19bb2c25f6737f5c1ec7e4ee99584566129541f6409ca967002", - "0x02f870055f8459682f00850681a1e1e883011e6e94b6806650a5345da2a7c119648944a52e7faa0eb180841249c58bc001a0cfaae544330304abc1a7b244709bdd95466670dcfb751131a738b55b21cd2de8a05eff056d772e15f8a0b17d7ba3319c2dbc3e0faf702da9b9cc17548646715b49", - "0x02f89605238459682f00850681a1e1e8830143f694fca08024a6d4bcc87275b1e4a1e22b71fad7f6498607780adec89ba42424401fc2d21c43c2c06181c9fc2e195c9fc98c50fa9b950bed6f9b0ac441c7733f5efbc001a03207f88fbdec768ba7507ffae042c87cd584df18230925b0880f86e30c8b9bdca060425536e71f32569f81fdecad0f241d29482da0ed10453a5bca86e1aafe386a", - "0x02f902fa05058459682f00850681a1e1e883035a13944648a43b2c14da09fdf82b161150d3f634f4049188017896703a310000b902843593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000006452a3a800000000000000000000000000000000000000000000000000000000000000020b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000017896703a31000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000017896703a310000000000000000000000000000000000000000000000000000009ea22ceba1457000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002bb4fbf271143f4fbf7b91a5ded31805e42b2208d6000bb8178e141a0e3b34152f73ff610437a7bf9b83267a000000000000000000000000000000000000000000c080a0147339ebf27e4d658d4374b924908040bec510b3b46869a30a9bd2d86100a08da018a58049310e8f225899ce7d5209a8dfedd470d03549e4f692c5394a00070819", - "0x02f9015805308459682f00850681a1e1e8830f4240949051dc48d27dab53dbab9e844f8e48c469603938872386f26fc10000b8e4deace8f5000000000000000000000000000000000000000000000000000000000000e704000000000000000000000000be39ad73b0b4a536a40dd803d12c0c95970586d90000000000000000000000000000000000000000000000004563918244f40000000000000000000000000000000000000000000000000000450ac0242d91800000000000000000000000000000000000000000000000000000000000645bd6a8000000000000000000000000b47de784ab8702ec35c5eab225d6f6ce476ddd280000000000000000000000000000000000000000000000000000000000000000c001a04a6ff5eca960a9e66be70e47fc535555a45249d49d696f79c36d8dbda26c7d1ea02508b1ae55e5c1924a11c62ca2466a157a8f27c6c42ef7591bc6e59325324d1c", - "0x02f8740581e08459682f00850994c1c236825208942fdd7d8bafec4e7f6ca9ed3fee47748bcbff7ad68802c68af0bb14000080c080a04c1f9b05a05c7f026b883a4ab869cda4045d7cfc3d3a5eef1ef9f30cce7fa2f8a0076aca9ea2ea1c804c1820784d9686a67f81cd08b0104b4814303dfe54ccf059", - "0x02f8d90581da8459682f00850681a1e1e88302bc9294fcf56865e9ec7155e756d69d2d8d1e2f5ce89f868711c37937e08000b86437e8a147000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000011c37937e08000c080a0f7cb632fa397ea515b1ed6e64159f21f8a0ee0467b16e3676621d12aa1e20d39a054db860c11259293ecc48578fceafb37b80a2ef4fafce474e3825c85b54e3a01", - "0x02f8b90581898459682f00850681a1e1e88304520a94e5e30e7c24e4dfcb281a682562e53154c15d333287038d87f4f61000b8449f8420b300000000000000000000000000000000000000000000000000038d7ea4c680000000000000000000000000000000000000000000000000000000000000009c40c001a0da0bce3e44b5a31a70dddcde96f0a508520ec932b7aa38df34547e674316548ca06991a879251849043a801ef4fdaf56ee086f6ce623f6c2a157895e128233c7cb", - "0x02f8b7053f8459682f00850681a1e1e88292ba94b93cba7013f4557cdfb590fd152d24ef4063485f87b1a2bc2ec50000b84440c10f19000000000000000000000000e4ebcff8ae18b41975d6abbdb3af1ad4567fb1760000000000000000000000000000000000000000000000056bc75e2d63100000c080a00fcc8517181f6bf6e34a8d74e59ace2cbb57e423aedf2f5f0b92efab75ec5024a07006e7b7682ddea6f624c061538115c89b885d88c2c1d4d4e8ede601606b3f49", - "0x02f8af05038459682f008506db6c477c82b3da94d87ba7a50b2e7e660f678a895e4b72e7cb4ccd9c80b844095ea7b300000000000000000000000078fc3ce997ebecddac5dffb9e7388453cc8952bc00000000000000000000000000000000000000000000000000000019debb4fc0c080a08cfc1fa2c53b004ae1b342b881583cb89deec6181343981ce455a338cadc65ff9f93b3bf311664b16a3b79537013722202e9365ee144b203a7e477dfcc0f7188", - "0x02f86f0502843b9aca0085050db0c92c82d36c94525aa8524d7612be86463453636fa527aebb7b5480844e71d92dc080a08456a0776bf97b51b09b8545d4f09da6de8d85060b61b12285ebb346251f1b4aa007b81d83f164a52ee3b7271dabdf785dd30460788146811e6266648a45fd5913", - "0x02f901370580843b9aca00850ba43b740082e43394e93c8cd0d409341205a592f8c4ac1a5fe5585cfa8740b1e6055c2000b8c4e9e05c42000000000000000000000000fcc4c549f2fc1624b8e7ffe9129fe5dba34bda060000000000000000000000000000000000000000000000000040b1e6055c200000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c080a01e8adc7c62679fe810b2c7b447c9557063d1337ca851728ed3cb7961ee625bdba02bb97fb16d56be95a18e4e80a3c1ecf73fa3e2c42fac0ea4b13fdab509c4e8c8", - "0x02f901370580843b9aca00850ba43b740082e43394e93c8cd0d409341205a592f8c4ac1a5fe5585cfa8740b1e6055c2000b8c4e9e05c420000000000000000000000008fbbfe10b812fd58a30dfeb7651a605902dfc2d50000000000000000000000000000000000000000000000000040b1e6055c200000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c080a09ca3679989879ac543351db76fad65f6003e79c7d6a0933b03a76ebbe800b744a078c3e8641019ff2779650cdb6c5547845989e1dc20f59c5a9dd4faadcbae3f51", - "0x02f901370580843b9aca00850ba43b740082e43394e93c8cd0d409341205a592f8c4ac1a5fe5585cfa8740b1e6055c2000b8c4e9e05c420000000000000000000000002bff746b11ff2759d1426ef4652133647b839c020000000000000000000000000000000000000000000000000040b1e6055c200000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c001a0cb0fcdceadc8ed2f9b0387921808153085994dfef125a990565921f7ce543ed9a032261b327ce30d9a87bff6e99c66ab056b684227fc691d2f8ae79ce1263ef49c", - "0x02f901370580843b9aca00850ba43b740082e43394e93c8cd0d409341205a592f8c4ac1a5fe5585cfa8740b1e6055c2000b8c4e9e05c420000000000000000000000007ddeca5ceef309a7e3e41e305c03d8f9fbe75b9b0000000000000000000000000000000000000000000000000040b1e6055c200000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c080a0d4774b09786fd47179c617ded5b1002593bb7e683ef2131dce495a4b2c32da51a0664ea741589fff7e7a276d255b58d6b6ed163f75b7ee87d0488ee9d7bd16f7e5", - "0x02f901370580843b9aca00850ba43b740082e43394e93c8cd0d409341205a592f8c4ac1a5fe5585cfa8740b1e6055c2000b8c4e9e05c42000000000000000000000000745b4cfd9e596329f884de779c6a854954061e4f0000000000000000000000000000000000000000000000000040b1e6055c200000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c080a04a8c40f31f54f1a2fc9262cde2058d8cbca457cea7e8d78667d0abdb7870f374a028efc22ccadff119eab2ddd00293ae04c04184115243599bdaf0ab639c53975f", - "0x02f901370580843b9aca00850ba43b740082e43394e93c8cd0d409341205a592f8c4ac1a5fe5585cfa8740b1e6055c2000b8c4e9e05c42000000000000000000000000c5e484a71c195efa18a84e2f9cc635330ace95640000000000000000000000000000000000000000000000000040b1e6055c200000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c001a067c47b9dcb54808759af8bee1e1810f8db0bf7e25b334ad5b46ee80507c44ef3a06aff44242ce8bf40db87d23ee77aba41705e7f4abf4675c353aa026dfd0cb268", - "0x02f901370580843b9aca00850ba43b740082e43394e93c8cd0d409341205a592f8c4ac1a5fe5585cfa8740b1e6055c2000b8c4e9e05c42000000000000000000000000073fd5263516877b570cdeaedbd2ae5c87e620e00000000000000000000000000000000000000000000000000040b1e6055c200000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c001a0576f79ba8919675d4a9a49688b076e8cf2933d899075911e2dfc2f6ae7901b86a03d86ebdb3d89042ca66aa6dcbecf41fa1eafd848d39551bae41f92249bc94115", - "0x02f901370580843b9aca00850ba43b740082e42194e93c8cd0d409341205a592f8c4ac1a5fe5585cfa8740b1e6055c2000b8c4e9e05c42000000000000000000000000dd88071f8831a943ede5fb85e8cc7afe8f5600f40000000000000000000000000000000000000000000000000040b1e6055c200000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c001a0393954e11c2b018d00279d6b1a3abbe9c14d258e38cd039ed1d0ede7af85887fa0055f90d03ce9002a6b9a084c271bed62e15b9187868e49821cc5623cd066f225", - "0x02f901370580843b9aca00850ba43b740082e43394e93c8cd0d409341205a592f8c4ac1a5fe5585cfa8740b1e6055c2000b8c4e9e05c42000000000000000000000000edd16349db7363ac220e9fbf950c0d10077be0560000000000000000000000000000000000000000000000000040b1e6055c200000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c080a0463558d61223a0b40414c16a6e46c80f3b5c0f38682947974fe57d52919d6e87a00531d35e294aea644b9b0cf5382c12f32238bbb5cb0420f88b2f015c0b6e2d56", - "0x02f901370580843b9aca00850ba43b740082e43394e93c8cd0d409341205a592f8c4ac1a5fe5585cfa8740b1e6055c2000b8c4e9e05c420000000000000000000000000ffbeb141052ac78cf79b69cebb1049730b8c8ff0000000000000000000000000000000000000000000000000040b1e6055c200000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c080a06b15d2ccf810b0676c8a38f6bf7689a7c69d98d4de58542686e357134a8fd307a00bc0293f67af297b845d257cb18b43038b25d4844b2c9176139139ebfdafac7c", - "0x02f90654058205ea84389fd980852a2b97e00083062c9294cd9dcc7b0a483a91ace0a7f65bab7ce0f5a0c20780b905e4377bb7700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000005645322843000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001e0235d3fdc4e07785d8608fe555e4487b0fdf592850a2be90c848bd229af933e691f9fc05952bf64866dbdcb43d67d8374596b18de5d7661b47045bc76bcb288101115e379a2241605f347253e7174c5018cdee8aef13185dd490e198071cca58024101d09ff5b3a728c8b3c80579f84a7d2237d93063b446227d826e653efd88e0a49f715684e5427395ab4954023822c46ba515550882d0ef7fcb4495bb33bd808646b86034b4d95b74cf15f618fabe14d5558a3961fbc88c4e5c9c88fe9064e1aeaa9909ff455fcaafeb40a52736fb17cd0d1f355eaf4cc133df0136ad6232315776249e89676b5b7f6317db437fc2d63bdc90a7b7230e8142ad67eeaf99a460000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000000000000247082b6f85455da807ce883e5520c72340dbcf7c7929cfdd1cd1484b7dbfd2f37fafdde44b0d815089473949f365028abe97ae9ce0179efb5b68985b2b0bc839c922bbaa9a523b7d63762fb4f641195ac902164df3135a39aeff22e717d136285bd86d88438f2a142d5dd06f1451c60854db9c9ad90e79064eff12271713032491c6e084f505870dd63f83b1d17d16b0f45abc81db64529c680012000000000000000a000000000000a400000027000000005540000014ca616a5ac9233c800000014cb34bbffc67326400000014ca9ed50ec788956000000157560e1a0387758580000015759e68ae36dc0cb0000001574cb2bab00000000ea400000027000000005540000014ca9fa358c787d9b80000014cb32b8dac68274600000014ca3e38f9ca2bb378000001575c1aa4e35d395b80000015756012fc38781400000001574cd2fbc00000000ea400000027000000004000000015756826ae387206a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014ca97935a000000031000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006324285f50a0e379b2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c080a0daa7ad5482faf72511c08bdd12d7726c8beab9ad714175586ba3b9279b844a35a06daef9f114bd0c85a92a791bc18cc7443b6a1a03a9b0bd745fb82449686c9c21", - "0x02f92855058305c8518459682f008504a817c8008353ec6094b6379a14b9cbf8d7a5d98db05792c5f01326da7b80b927e4e85a6a2800000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000232000a27871234c27e497d2562f347af2cd5d11fe27624a827450c3a0d48ce6ee480000000000000000000000000000000000000000000000000000000000000003a58f62d4c6666c33faaa545751ec22f607e5cb7e000000000000000000000000000000000000000000000000000000000000000000000000000000000000011302f7fbc7fccbe10ad8c11ab4276b12e81511c0fe3e924b9182fef6190ad87c640132b9e57046bd0ff76a6399f34e205e0ed43b58d98dfab4a9ed2fd901f4ef5f054104843c4e8404f13366331aacae698e9432f75b68bcc53b8f09f761060bb900e08a0e3e2d4ed50195ed5f7b2321bbb9c0415a053b8567d62d760c83376a6a01f91a9bf3a07fbb6fb986c20a7b203b17feea887efe85436aae8d7277dded540061367e145555173824c1f408748c3cd4e9778a0e03d4ea6a61ee6c1beb114905f061ae3583fbda6aab548a9deccd3b08751edec738c4307caa72517cf17fff03f8bccd09045f5c80cb85f5f6f0a4768a30c51673404c7b4e7e6bc0855e921a066dfee8092d05a19f3018210a3ce4833eb44800cb1f7caa893bc2e080ba94b802c2c4919e9e038c034f7266fd3ca1bda0ed21a7bba4ec397716952cea88c5c80680e25643177d86ba5c9f798ff5365042ae5ae0643cd1150c6e0baa9fc354a306e2ec681be1a4642dc765f64efdc3affc7cb2a78489e9cf3ac3f808aacbb54b01335b70ac028cbc15d4289ce6648bf13e8064bfed0f69a1102b37812fb12189004c0af34275ade15c54474bf9fd009fde7c60af6b5d4316b0662b3cd49bd6d400d20cf60fc79abf9a7b6c083c4744c3528b194294a69cba4b3c19107e3f149506ed2a7958e5625486caebfd66f9ec0c3417a806b9ca78ed8ae05b017e5917a207fe4da00a2f8f173b2c731af7ac4ba51e26717f28620771a4e7b9f482d762fb05bfcb80afc2b5b6662fb73546e89ab5843847e1d22c56872cea6caee9a8296107e582a4cfc8f7eb6e828c159ce30fee5fbedefecb865cdde0135a455ae2920c031351df766df4031739cbc0d176e754dab641a71a4595f686a11197a138ef7006ec890438da08d0c7b7d86e8b5483645905eecc58298703e53dea458d17e7e3039c5d27f0bfc1d51df7705cec06ba357eab3d2a5d5c263b071c7f70ebf24c0c004cd546e8bc8c0ac91336128d98ef8d6ee96e2ac9641a750a7598439b13f79a005f88a86febaa73879e4619d608ff823340eb986b05f644cf9575617815d4bd0685082a1b899f2097cbed00dc4696b6d20fd6fb75048da52d08d12e873e723007e0d15cc81ef6ca5b351769065441ea65285e7101b5d07c678a9e85271b015e011c5112e537d7a8d497b519819512968f44084b7e01a5e86f60c6f70a03f06b0687a5774de58b7f1a0cc4483c0f5737ed55549d0d8477ed2b94f3cbe1cc4d0e002b1c56bb736cc4b5c859e8850f57bf1041f664f6c6c09afa27494ef7ced37806a665967a220b9a471191af9e63fcb9f47bc5727a865e93ac210a47acd967e7003dc0afe2c260ec7c0b7994cf8f710659d05004a63891a56483c96c505bbef803efd70fddc3fb0b3dc6b8b02fe89cad0a0309a3442dc2b58500ae731c6b3b5e049d2c19440ecf394a432fb47f5a8341937d398714a38bf4e420dc36350cb209005a5bb969c2beb2510127c79733813ae4ebf22169a1fdc509747f33b02adad901adb2dd72fcf96c707060142ebc9b55ea1f156589ddbc18079b88d306dd1881040f6736f6e45af8a4bdc56d44d770a6342766890869b6b36e280546b3534d1407a9a43b6d062a9be948707668301b837e7e3afd01c041892c258440eefd15af07261836105c73e6a7449e1a904ecf53447d556ece4686968ef4fef4c140a0ef0698c95c359536239909326b82a55089842fa60e2835f8a247d2d5d3e1c5bd4a053133d564577dd136e93f456f99a75cc4b041c24ef279d939cafcbe703268cf03ed5fd8b9367b5755fc8fc5958ccee69be6204ffd249db4348dc6b9ff48e7f604fda5adea6315651984b7e4bbe27f615195947118618470182a466212671751029c3cb273e0bc19fcb68f2ed8f222483f6f082f036f20ceaddd629c7b3a952906686281e6510342e6866a0e21b785ced459a5119b1ddc0f52d7f2717283ff32060cb45f3b283150f05758d6da5c50a6ebc0766c9c65db848f0bcc99d42bc851034a6c0eb96ce2dc4d97bfcf4c1600bc12edc7e93da080860ba4387d744b497702b5e081b90a406b8ef1ec184bdfabfd7c899b0695de99cd4756b7a9657b08c90386aa98c133fcb6f761ac7ced68899921a95e5fbc005f47fd2e7b4c2d473e5a0254171330325416d2e7ccf70fbe9c183e296af9e261e75b47e3e05517f70fef01250733046900a2239f0c20e7a874735362bb0e75d92ae93b09b12138f9ef7b0611482aafc3ad87eb0ffbf54eb9eedfa99ffad5d2a05f06c34fa8700083342a03f24466a78779993e6eb6f99271d4e65a90340278a12dde3a16f17d1f6faed405c81d60b30d27db0f38dbb7c30b5061c2ddef429706ff8a2a989fa7761b516a04eb3c5b5b535c1c4c56eea19e4a8a0074669d67aa8810b8333e1cac3c1417a200bb3077c9fa4514db4c0d43ac518e6b6750f23d6eb547118ef1b69493d4447b066f37ff1d03b04f9421e62dc19cbdf5003356b316bb0a2e8aa75e01581215ad01af9e", - "0x02f923d5058305c8528459682f008504a817c8008353ec6094b6379a14b9cbf8d7a5d98db05792c5f01326da7b80b92364e85a6a2800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000001ea003e50cc00ce3a34900219abb5440b53a8860dec5288f73023e4bfe9f8b132bb800000000000000000000000000000000000000000000000000000000000000039a0574493c9b238363e25910a96928e8e912454500000000000000000000000000000000000000000000000000000000000000000000000000000000000000ef03464c373d8de6a96585e4a6e177b1dd624e113bfe532cc080c9531ee03388ff000a5480d129f82234345116e16160be364d4ee43e28a3008032e9e0a9c7b31b033b7b07fdd6e72f85249a3a30d5aac61731cccb9f31c482f2cfd220f7b888fc04a79f6aa04714d6439bca0e4d17fa544b1ac560ac2f410943c3b67c7174e26801b3b2ea6217f20142624e356492c48d1ebb9007c77a9ea35670b7547fcad4a3068e38dcaaf1383e6581309c46f391a1e526ba53f7f983c62f89a686e60115e900da480e0637d05d437942ac4dfc86d3597ff5bab691d75a499bb86829725ff202899c4b4759d19d0a389a549239c279a7b0c14f3bf7a633061a0212a229daca06391f022b221883c387bc085f625ac638c1b7e8fbc9597b7b3f832d81bacc2a00830313a4c55e2891982653444d05412490ee00192ec9a478c6dfaa6ac8ab3c05e46b351c3df7a3afa40ed615bb6f077479b6d0f934d9f8cc3e79a6efbed3a50156bf97f4d5c49350b74195311a14c9dd76af27bc759099d136a37570d72870034353d22d120d249bbbecbc4c8ee2dea5873644755e613c764052f6df4f26b407d370ef4fa8725b097f723a43c6e7e3bd72bb603152796779395b96fa4ceb4304617efc893656511a3fd4961dddb589eaeb6ea8c4fa0a154c7838b1ed7056ef0682a27021c163608e683d55a7c3a62bf73316da6c7ea263f0fab26011c5a79304060be87a9e4378a40e09e93740e97272ef3eb3c51920c34466a588746682ab051a7565b7ca2d1b79e250dcd4ccf0a0fb5b6d5b2a77e63eff96204d0dc2a4990672e33ad069f28cc20154f2f40b0c53e37b6aa4220b1dda658afe993d62a3230095d09e0f58530734890d4cfb89d7baa345da20f7f10ba6dffdcea3adb2f7f6012d870d06e9dd46fb6d9a9a63788747ab3b5e10e845804cabd76ed8350aa2b30128a399f39f4a5699ad982d3afc8fe335b9a861c222b9f2f2ed5b77ba87775001a4f061751c5a6049371798459b70a0aea257c61ca1b167dec50760eab8806003cee6df3cd28c6339778500ae5d9b27a13325f407034fb81f83506b9345f5af07fa40764c8d883a32e90e832836fbe5071e00c17fae0c10acb74cce1d8488cd0401c92ef976d7a1538c676b96167f1b63539bf0d95e27304c167e2fe43436c002ca4366b307a2f5ea4c57c848cba94399c71bb01907dd08a697606fb53a24ef0333f4c7c7b1f28aeecd51ed230d2c4a73d71802709229aabbde51f28090c2f007cdbf1a428cf92e4894a734f64c86aa70e405c0761471090435507121dd7cab063a64295df775665fe744c84e6144d2f4aa6cd5480c84e713b2932958367e4106a7a0baad447a8fa45cf6921565d1c23474ead63170fbe3dbcfdf8e1f0e0b0b0656b9f00b89dd4efd042dfc76d534fa3590e5decd215e81d008fd36d0a4dbbf04e347c4c6076a96ae3b43060a3c0cb58af8951b2c9dfcb08a500a4e58a6d3fb048b6ed58116a2a0439381c396081903b023d1bb7f4394b0f2c1089bf1250f52037096644d3f5a0cfb180018099b68a3ea3292b1e489bf0cbf2f3dd5a0e4ce04002fc09c165095ad97a7d1493e2d18e9f7556abfc0ad12622d213d290fd3f19a05ca17603d0800178027c9dd93656930ae0cb4195dd4a459f2534cebd984306a04914377b666becb50726deb1846d788551a5164ee44d2162fe0f0d0c5eefaa9010ad9dc569c0c064d0ae362b395147ffc15d48153243ee20b62ab02b107a132075970f290b9ca121e2eff4314ac5f1b36813cb0503cf762533edd8391d7efd301ccb6b1224580856df5d02cf630fb23fcbf7270ee561ad02783fdfa1e4c27520336b6c89dd95463df5986703a9ff03e2bb935d8510f6699fccf587071a1db6204cc3378ad7c4d1f6b8893190fe47289b049dd341cbc71b5d1590674358bf500025e48a0f2e8854a8bf04b18fb8af9eea8a07f9ffb2b6bad1182e23191a233a50787641b2a3802132147769b43b2066b5b799316a1569e5d139ad1e7d664ef590669da421e552e0c378976a4878880f001e70a0ef4ab73c455999ff3ac58e8560296cf5d51264891b033ca14d65762b8682ceee30ef352fec86f3bc007b38b8c05eb3c00c7ec1e8ee422ccc42b88e73960fa66e8fb3f9b1968d327e5b2160eb803dcf6106d2f7577f91c01613450f55902e76d8842224c1288c56833916491ab071350fc9970185e67f54d2baadb3c7f2ffadc39dfa558ec336d1b771dd7da1500d16e16ca6764fe3c1f1db7367dd6b360a0a35772783cea02a05db09d1293600621f47bc63ea19ef08f79b1a8565d9ead8862ab74c8b4560d05dd7e0668a31f00105f92c89101221202b0487c8c6e5039d30e67769d4f943ffed0001703c29501acb528aba234d44c7236fed49291d46ab55bef8b345021fb86753e2d9e4a4303d182b5a793f2f858b1b03a58e98755bdde25fe67afcfce4738433fbf9fb57506713e0e9364ecd8c4705284fc79fdf75057a819b009975a06735c354f9f2e3101956c", - "0x02f91f55058305c8538459682f008504a817c8008353ec6094b6379a14b9cbf8d7a5d98db05792c5f01326da7b80b91ee4e85a6a2800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000001a2007803a5b51bf4cc540c19500ce0290ff802f97fab1767df58277b66ea3b52811000000000000000000000000000000000000000000000000000000000000000303641f067702ab9aff75c3dc0d21369f9b6863b800000000000000000000000000000000000000000000000000000000000000000000000000000000000000cb05488f333b9ad1a1b14d581996c08422ecdd2cffeadf02cd7b26f11a935dd27a06b285581b6a86dfd731a142ddc4d734b42fe3457590cd406dc53801962bc894048eaa2e6e3b1a6bd6fe1892d8229319446e67b37e0897afde8630be2df5aa5201a84338bce3abb1cd853e56346f4e55b0161c1e765412e8dd4e30501e90cbf603c3e0d344230ddd1bbb360b6c310865c81146f0d7326ba34ef3d1f3958f2ee102ac405b95bf6c11b316fb1f09fc5815eac280477f6dfbc5aae5d70d6e2db7de020dafb024c84696ef47453014fc04c9b4b49b3e37cdd154ab33ad3421d2be660064fc43c2e44db6dcd820dc07c5e3a8c9f02ad1539ff621d513166ff944e0ad012e81c02a5bb2229509112e3ff3add1a8672b377d03f4fa991dce2ac9ac85ae058e9a16af9d04fc67f6c7250193f128ef56a2539cd5ec53a86d19f7c59ac72801d98204dab0577f9c33b88eaceee5946ea5df20b89eefd3d539b1c605a826d00776c5327a04fcb553e4d98e023fa145113871af2d44605ecb7f18b6871578c602cc7f3031816b0e6dd60215aaa876028e31ece0fc2a97baddbbacacc44bdd2703d12563f0cf5cbb0a09d750423a1dac4bb839431fe5d5b943e55bcfb9f13cf105d5b776922b1945eac8fe21f4b36593557ee4153702b308baecc6afc393c2b10696c62028311d4b021b8d9e6693ff22ae1d843cbae4730727bcdf08c7e88a7c0627327c928b3aa8fb11df2487047e15977059cf50250eb87ce3635a86f251d9035379685e3b45673d4a2848be02ca134a4a7e2553729a83413d164d48b2c1f001f9e5c4d3fba67565be241170dfc791584e377a8ca8cb667ad5c49386deb02102582c793fa20eb5f4283baf9c9b56962c0e83b2d41b4addd72407daba04714c0083d7c6467b5c7c6f3b63fce75bf7dcb649014d95f4ed6e372888606fb507830432175445fc2429631248cfcec0f8e0f791b194e5cf5e2850ecef53b73ed3640108706677511e85cc86ee58f0c0049d771b37c71cd2e7e5928db40b7d1adb750784eaad6770879ffb46089bf176e29997c6cc0294101b699d358c73f2dc4f140239e8f6acbf3e7f4b1b4d9e383ea4ffc954f5f6d2b0e9ecd116894ce44d770803180a73556518f8a74e08f4f98b4c77ccdb3f6288c620ec2a4864d9396b860f02da3960a8352dda428e2fd55befd1555f11f38eac6186e2ae0f7494e24756e602342d6fb6ff3e706c735adcbff8868595ff2860ce80c64519c6c471ef0879cb02fa87bcf1167b3fe0979bba3e695a18dceab76e0218f7765fd20461fe4fee270463f60441546d2986247a2c2e2be0529345898787354b21974f6c695fe743e305b7fbd6643100e5ebbc5541d90943fad4d54a61c6d9c68a4ea30f834c0615ac018ce4986bde43ab0d94128e35e523912cf29d34022f9990f009f6aff550a10600654885b921c3851b8c2fdd7cda773c942f30db671cc391cec1ac167a40e5e301561375fc26370ec4d3e7838aecb94c85c5cdde9252ebeecf137139fae202eb01f22cc2b6c2acea46b143ee8d73b08122525d868c6a400d6b1875a4d3ecbd5b069cd909020c56c9c84904653cb3f1ade6d619617b913d99e13464fb2f15e4d10654d637dfe2f21cb7d0eccdb8539537e8ebeedd448af159a2d90011ea6023ab01e5cb78de77290be45c0ebd3af4a2f187de59cb76ea2d9ad5204da45bb549d5067da7ec6d08e94e74a5fbd5efa19e9f2b6ab057ddda5d6c61b7ac80d4cad9ec0064bd86ee90b85e530d61ff4ca57da92bbec1056a5cfb018b2ea31abbb9b55105cf237d228605876608bcc6ae6eb3417151693c06c352ccaddf66ac3645afd507a3f271aa08cd000ed88fc84c4d788b03adee5667199f85297dc948b62db6d402243ae0a0bd8bc39acb9bddbbf007a15e02127494f5781a7fca0a56f9eade86047e882a2081e8be4093cba09c70b1677a501b07753b7f1f345790f58fd26bad030196eed34309b1da84e458457e24ba09e77880bcc3e30230767e678634c46000a444572f0d9ca02c231daa732346b5a3b216ba324ba8c7264bd29d7dab049f071e7e895b95fdd920d1eba20d54fba7b43ecccfa08accf2f8034290714f5847000d5291168c069496dd2b655c893c721c0beda4cec4c374c086dcd3e61653a6018b30c54efbf11990980d259ab97a6f79d88268d0cc3377e58dff757cac7bb1038df5bc54c8435995f358c1ad961c8e940083c996b6336ae835e4e607e8628c0744a978c4e56889641d67035f8a2aba4d87ac164cca7929a5c4182d5fe6a7790293151db3f872a041022068780b5f4a6cdbc178bb9799f62a85f745791f24f504a46e564ffd22755afbd8a70b3869300c516dfbe52ee2f2a6ea98c2640164da07b31a76312745481e7a0dccbf6e641d524eac2c0f35f3970854bfa1e6ea075d070029e6803fe5570a1cf167dc49a3adaeb243443520fc6831b19935085d3158076b459b7b66dc1577545885f8eae12dc210617367f667046a34e4d876c3c6aa0573a6", - "0x02f91655058305c8548459682f008504a817c8008353ec6094b6379a14b9cbf8d7a5d98db05792c5f01326da7b80b915e4e85a6a2800000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000112002cb839645e4f926fe30710b52c66593708ab1689fab58a135a06dfbeedaaad200000000000000000000000000000000000000000000000000000000000000020ffcbcd18579d04d2130c01e3bcd529f800788880000000000000000000000000000000000000000000000000000000000000000000000000000000000000083053feac0fa855871be263f6fb61d87256280168d07a939adfc108defb1d4616e0089e260f855ec7009b8679664ac25e8c350239811a5c500f28499569f17c7bf01a694d2de48bcfc887b418763374a3d954645acbb25f1e0fc6d815b93d0994605a4eb327bbca14ae199689c025c13e58332f37f10afbb3275807b55d8f2a8c4035b858590bda079d96e669bddecc4b1da2fc0c0b13ffe8ce58981d732afbc600232817e89408bfbe6b9e2d09bf61e581e2d8a39e7f258c00ff4c05ee2cf5b5f049080d70e4fb6b08b999bdc2424c0e8ab175bbf54c58fe990629cc836c301080570f694bbe2fd849dd95442511cf9a6a30142b5bcead1ba8eec285f1d26ec1b0013d421d83f044515bf47842ec63c8063b7cf5f763c8e37384f8a8fb0bd70dd05af336a72ee4057219167f2219e725daf7f42cb57e0087438b35093adb72b8b01d54f76ac660e3d9fb8b0ede481732fb8c5474d3a92f5cbe67506ee47e7eec5052a5c3dad3e8d6e3228cbdb8e3cd1df06c323516f77eeadf6e3ec0c4ccc694b026b3626bfc1397fe447dcc9667f7f9ba988469e5a0a770559c90b5d942f9e7700cd7e955788329f94c2d3ab52104423c4de0da84ca58b4f6f851551469dde55021aaf9aca6f2744db5363c9456c5f16fcb4cbec4b4aa75884d9867d7872bc43075f8dd795a0daee0e95d5e356946253b74dcc85e183a10e8b3d24c301798b92026746068f3002975dcef4d6ee80cb60df78557a2f05f0dd00efe1f29e7d0f18043d7966b6c45a31d9d535c1110030b24875cdbf5434362a2fb1ff6a472e892b05f94b5809ce9d12bec9d40717120fcaba12d0de3e74a3fe438ee260702c8e89072157d776ee214a856f5aa796561d47d1d9ae4d9dc8bb46750a36caf3620f060462a80f00c68bf3632e2dc8efa32d2e65b8d69f27fe306e0ac2e76e1f9c496302defd3d9c41250f0470fe31a0fbbf1ebef8430240ad629b49c4f2d8a49feaf005869cfd75df412619b2aabaee8058a4966b63605b688efea0bd72c7e6fc19b70165e7e1ab4806c0051fc0092fee7a50738f60c3d38d6201139f788d02910dc5002ba05b6e865c746a0a73060b8d5752b12aee54a8a67c6ffba02ce74b295f8f072ab54ecfeacd665df85eeecf3d89b30dac1d4f326dc94fa31b567407d1e38100d173635b912737ffa028847f3d5cc162583aa25a480275da2739a2e431e23e032c870f0c25f560cfb537e12999e4627544bcf50c63fcc4f6979703005b3b27015757a6ef3a3e27174e27996b6af97fce7861cb08b1ac8bc72193a1267e13af06a3c533a72228ed4ecaf4fa70793a645bbe38df6e263b7e858e596e4ac30717072009dbb9aacca3c93a4daedcef824369795839d1b75cbc984c02ba0fc3751e01d8e50ba6ad40c2ff801892a6a82c883fd030f72c52a5512b0575ea10f2aded05cbe028b0f89962407e4608a3baab3650b392e8faed799654b0f57f89179e0704e72778f9d74685fb39ef5e7774066d3d96dbd7c470289ab5c7447b9a8ba094076097e8b285cc4ac758548e36ff0d677901d63caebdb2353f0bd8e666bbd660049af79d7e06d197d24092623cdb60f5d9ba22599c818087c1719734c75be94f3737039378be6fdd7f0cef6b5d6a98e1066860b10000000000000000000000001795050119f1139d6aa292fc26528e9accad3a46000000000000000000000000701fdf7b3605aef2fbc5db1c20f95a0e9f64ca3d000000000000000000000000ae6bb538299fb240d9b19e61f60155b87b4f587a00000000000000000000000098e05c8f4222b710d1244e6b6e6683ab60d8ef0b000000000000000000000000132a0cd86c843abec33d6e1410b94de34528e469000000000000000000000000f1e71f42fd0430564c7fb51ac7f89a3f698e5a0d0000000000000000000000004cdf2522eeab99041f8869aa128c232de91191d5000000000000000000000000fa6f5aa5cb21c7e0be328cb9f1585e99a0ef7a12000000000000000000000000c4107cb031b807deaf592827a5eae3628d0165960000000000000000000000008269e5088847196cb46930a54af083b285fb969f000000000000000000000000035f6acda8d1b2836b9914af00bc4adae844a492000000000000000000000000dab37f6b7c13653181adbeba8c3c8a1d4ad947ec000000000000000000000000090e5d93908121cda73e40741e3d0b97c4d9021800000000000000000000000032c435a64d98b2b72e092f71b613034a56f3cb05000000000000000000000000e83a7c63b0a02ffb19e9672efe793defc7b4305000000000000000000000000010201c9a9ffd00024d2a0709d441f8b06dad39ba000000000000000000000000101c7fe19424adb7d6f238845ebfb3663f15694f000000000000000000000000e6f0d0fc3e4045453e074106adca32f556a4e61300000000000000000000000048f91e8c90aaa403417c3d195c953504baf31a480000000000000000000000002704d6", - "0x02f91355058305c8558459682f008504a817c8008353ec6094b6379a14b9cbf8d7a5d98db05792c5f01326da7b80b912e4e85a6a2800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000e20018c78eab59df24e7af35b4ab3cfe1724b88f0bb0476e6d65fac04dbe18ef02c0000000000000000000000000000000000000000000000000000000000000002b15ffbf11e5bdfe43d1c5bb9d4fd2c12d86134c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b03c243c715a9ed8211eff9bd1dd8eb5c61101cc77e8d94cbd9e2787ae333b39806ca7e2454e929ea76716fc1f3271b303c6954cf318a5248593261bfbc06537d02f3b6223377c1a6ad6812af9fbc2f3c6af2df37aa3fcf2bf95d50abc6a38b7206162b3e142653b56c5d29cdca3c0fd679f80db28cbba2f2f64dd2b59427487b07fb65b5e96db45cd4e145d2e5d123547cc9474c6aa8fb6fddfc6b1030b2a8130641e6904450dcc1bb097f24246107e1545118feabc41b7ca0c930f1dd73842400ceeb4202be3f7451d65f7465518278ff0bb42a0b20dc79ee989f9ce35de66e0301713de188e21791f8f62a8202c85b5499636f620acfed8c51d2129d0f7dd507751e5b2a78679cc82f6c74a2d228e3719c19a584110d89d02c9acb754489d50446e18b0774aa72d297eabaad94930837b5dbe7e956214f6bd10a9b5f8ed24304ace049635d46ec0f4b605c9bcc12b23c76cc27168dff4db654914c1ca002f0075effa4039d4bde74ae943c91569d50875f1fbd8bd72c6c37959691f41376420092690e7607383514b836e8da58b15acc7e13f1758c66748cbd7278785ed7ea056e99098d1865b73dac7b1085ca39f22be56c2d94ab94594f1fe15c6f6097e300b5918259883e5837bc9f6eaf4c6bc0112d7c9db2b0d384f8f02442f4ea33bd01749f8f2ccd6e14dd76144a227b10cfbdabee6097873b3ac10e7e081e313bda0528fe9ec75bd4a5fafc2b09035a87bc4060c4765280825dbe60b172882048b0060a54f18b97c9155939054adba6f6c283f4a35e38a1be2fa0c0de8ad56c9511011a1c6dd687efb2057ed720d1f607758172f81a3d3b3e7a0efedeb6aba2bfd905e2b861296d5a619ec71b65a88d49509b7b9bd011809715b4302a22a4e6e5a7007a2a77fab13581bd866cb1ef5bcb92ba68da7d2b0aa462fb89a42cc863f910043ae3e76984a5a6d2fbb27c5981b0c9d682015a28f3e06b549d9004c4a16d94065ff341636d8252c6f5b55644b3337150abc849b5a3ac72c5275194b9b33142030ea78626b4a92a854d220a9241a2be98f0b5a3868363e8bea0e9c85cdd32190337a98c2095a43a1223b1dde6868dce6e3146bd96d1cebae5cafca7a7eda6b3079691a6f0a7fab3df5d99c1a91ece57ace9fb431901fbddf6e6d60d8156ee0804477cb17df80834665d8f5bc9a566c68d53bc10950f13aeee95138d10d467ac04eb56c0c88b0c2121c462dab4ac50851c9830a12fe1033c0ba051b5f4a181c600e833f11b5bf0ce7511be4363ba87f16b3dbb8fdfbac3c2aaf818590629a8f807db39b2ee6f1ecc7b952d3de9223c748366631b1dd2a10911f9a6487bea288703ce9375c1dc1687ac19cbc1823be2afe8ee29880dbd2c58ebc814d96f1cb78a035a16627975477843e9d93e47c6fbc121eb6522a2855113aee01dec687077770454a8d779bf70c0ec9d597185fa3a0f2c967acd8dfaef275de2a9a3eeb7d61905aefc2f7ec212284c5e479b78acff7e98356632a22a162b7eaddb6a6c398bb3068ba3827b9e06bf173a98e551e5f6c3c2ffe1306c4bb5ae4713bcc54d1411ab0682f85a0ba19e9120f8cd86568655c6b0312a08e4db6b250f159d3f5cfbdf32c9650bd49fed92c58f4bb2be142fc0b102bae4470000000000000000000000001fbe904f3f142a9c458f4907d7e12fa02403c211000000000000000000000000656fabd579666b3ed18529eadadf7e0c06534a7b0000000000000000000000002956e656cde6491fdccc490d7d5263a1e5146ff0000000000000000000000000ed7dd508f738cb4709a4f968717fac37f72db4f6000000000000000000000000432ab65f5fcd9e7005ae951e1c9049d14433a63700000000000000000000000099d9bced2b857f2e6755c126d6ee5eb5fee52d5a00000000000000000000000011a36db5014b8603886992f22eadfacc24c136740000000000000000000000001ef230d226086347a76261c80c06483f6b67fc73000000000000000000000000849a0ec976fb8324c7f58ae5c57fa496131c00b40000000000000000000000000a445dc9b57c3bc9263a12040336655f0967ddf7000000000000000000000000f3d3b7ff7321a4c887478c655a9bb6b5d562b144000000000000000000000000a54eeea45651acffa26f3c57fd40a98604564c990000000000000000000000009449b858ca68a343601b4fb857d1681279f34cab000000000000000000000000f87cd5344145a53db61d09b76bac6315c8c5e9fe000000000000000000000000f38d2de110c9bcdecc4b7af23c9a698476f5e37500000000000000000000000000836f22570d729d01def427cdc2f46401b152d7000000000000000000000000dbfea5a6c8a8ac8c8a7dd62c268a596c40ac6387000000000000000000000000640bdd7494ad7c60a4ff9ea7ad0087dd554aef99000000000000000000000000a5898ee36594fc6def5c71edb78065c0eaf44de1000000000000000000000000666deb", - "0x02f93ff5058305c8568459682f008504a817c8008353ec60946df799e080759604d07da4a4595128373beb5d8180b93f845578ceae0000000000000000000000000000000000000000000000000000000000187fee00000000000000000000000000000000000000000000000000000000000000a003b3c67a664f5d65b365bf2bb47efa3207dc193ab5e4316c16317dc95b964e62022e04418682abcb30d8713a920f1aca67a9526684a91c20b02c7cc50c0d9dbc080000000000001100000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001f60353fd45164ddc943332669b8d4743fce7ef1d1cf7dd820b669e98825f96997c000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000031494e43482d37000000000000000005cab5ba3db5941c6ce588b25dc6c9adb565d805629b2e4dd8e7fe6eeac303c10000000000000000000000000000000000414156452d38000000000000000000006e98c93ee9a4e7cc5c44d190f4d3dd08658428a4fdafeeca077a955ac6120d00000000000000000000000000000000004144412d36000000000000000000000590e0c79a3dde450452874a192b6f0c59a3c91b16bfe88fbb6116ee491d5b080000000000000000000000000000000000414c43582d3800000000000000000007acd949642dafa291ed327e123b50cf0dda9fc7a16fc655394e40b6c5f73e330000000000000000000000000000000000414c474f2d36000000000000000000053ffd8fca658ef8a853379eaf490ef3ade15f183a4fc816bab2edd083d182960000000000000000000000000000000000414c5048412d3500000000000000000652fa7c13c1696f321ef246dd4308a122ada7e7c0b04a6159e19e77fefd5a1f00000000000000000000000000000000004150452d370000000000000000000000181cb4081b256dbb6b067ef6668b8ff93d51493a4a738cb464ef02209e9484000000000000000000000000000000000041522d3700000000000000000000000031909be371a6eb458fa5971c19a496efc30ccc069b415abd23a986087aae36000000000000000000000000000000000041544f4d2d37000000000000000000004bd17f89c4545f80ca5f5138deaf412df9e1ed240bb16532ca7ca63496022f0000000000000000000000000000000000415641582d3700000000000000000005af1ade8046fb4cdd050494861b140fcc6d1966bfef56f8c050005e05b34cf600000000000000000000000000000000004158532d370000000000000000000000dc0f4ffbfd73f75013e59ea8197012db4de5f2c2dbb445bec1b8110a91ff63000000000000000000000000000000000042414c2d370000000000000000000002df2bc73e267940de23663550ae40e2ab04829cae6b3bf1ea47c7f3da449c8f00000000000000000000000000000000004241542d350000000000000000000004699da57bd2cad90fffbcd450dbc551b03a1d0659c2a18e967cd3ad5bbb148a00000000000000000000000000000000004243482d380000000000000000000007162a67b6de914bc616e250087be4f4b32f1091173a9715ed529bf49fadc32f0000000000000000000000000000000000424e422d3800000000000000000000046d4c5002da65edf23fc3f276ae8faed3b12bb5152a628a504217dc14e206170000000000000000000000000000000000424e542d3600000000000000000000012307627fd75b93d85a5bf1b131c3f04fe06e2dd1d42e0f69ded501d0b2383b00000000000000000000000000000000004254432d3130000000000000000000032d88804c27889bc102b55175e470c702c5271d4f47ee65609be48cd12ce92b000000000000000000000000000000000043454c4f2d36000000000000000000071925580daa4d3f23f23a8d6eadb8433d4d97f2d8a951fafd467e6ef58805e70000000000000000000000000000000000434f4d502d38000000000000000000063d090b8ae4062273bd544a98a30a8ee7be7884ce7cdc8ca4c76126cd19f4e400000000000000000000000000000000004352562d360000000000000000000007bfbb5c5cb2a8fd2315b19610cbadc839675cff0d07d90bbb38df585ad4a9910000000000000000000000000000000000444f444f2d3600000000000000000007872ede04c06042cdde553e4786f0190d1c0fda22c7122aafdc72786fa8565f0000000000000000000000000000000000444f47452d350000000000000000000566ed4ec703e17aef519a33b94b4b3f68539c78eed4f379a60214956c1f64360000000000000000000000000000000000444f542d370000000000000000000005ff2995ee5ead55d78716aeccd62bea78617c17ddfe3804f75e7a392e43a73c00000000000000000000000000000000004450492d38000000000000000000000627ea347822b38617158da472ba9e0d9ddc72ba373687e9721fbf5b5ebbc3810000000000000000000000000000000000454e4a2d3600000000000000000000010ff91bca840bcbd139cb2b00460f43f7a05c6cc5055ecd935d6a5693e29fd50000000000000000000000000000000000454e532d3700000000000000000000079ea2b418225dc558746a181f974c3f6148d586d53e776f1d050560ddabf0780000000000000000000000000000000000454f532d360000000000000000000006333c241da9571347aa61fd8e17504222087149377c2bebd4d9e985b4627ef6000000", - "0x02f92af5058305c8578459682f008504a817c8008353ec60946df799e080759604d07da4a4595128373beb5d8180b92a845578ceae00000000000000000000000000000000000000000000000000000000001881e400000000000000000000000000000000000000000000000000000000000000a003b3c67a664f5d65b365bf2bb47efa3207dc193ab5e4316c16317dc95b964e62022e04418682abcb30d8713a920f1aca67a9526684a91c20b02c7cc50c0d9dbc0800000000000011000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000014e00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000031494e43482d3700000000000000000000000000000000000000000000000000000000000000008000000000c7921b0000000000000000000000000000000000414156452d380000000000000000000000000000000000000000000000000000000000000000008000000001f3964f00000000000000000000000000000000004144412d36000000000000000000000000000000000000000000000000000000000000000000008000000004def5cc0000000000000000000000000000000000414c474f2d360000000000000000000000000000000000000000000000000000000000000000007ffffffffdbee8bf000000000000000000000000000000000041544f4d2d370000000000000000000000000000000000000000000000000000000000000000007ffffffff3b2fc8e0000000000000000000000000000000000415641582d370000000000000000000000000000000000000000000000000000000000000000007fffffffc6a6cf8d00000000000000000000000000000000004243482d3800000000000000000000000000000000000000000000000000000000000000000000800000000b94e91300000000000000000000000000000000004254432d313000000000000000000000000000000000000000000000000000000000000000000080000000226e1016000000000000000000000000000000000043454c4f2d360000000000000000000000000000000000000000000000000000000000000000007ffffffffde633a60000000000000000000000000000000000434f4d502d380000000000000000000000000000000000000000000000000000000000000000007ffffffffaec779900000000000000000000000000000000004352562d36000000000000000000000000000000000000000000000000000000000000000000007fffffffeba506c30000000000000000000000000000000000444f47452d350000000000000000000000000000000000000000000000000000000000000000007fffffffe750e93d0000000000000000000000000000000000444f542d37000000000000000000000000000000000000000000000000000000000000000000008000000004ba7e4d0000000000000000000000000000000000454e4a2d36000000000000000000000000000000000000000000000000000000000000000000007ffffffff488523d0000000000000000000000000000000000454f532d36000000000000000000000000000000000000000000000000000000000000000000007ffffffff68f0ef900000000000000000000000000000000004554432d37000000000000000000000000000000000000000000000000000000000000000000008000000003ca5b9200000000000000000000000000000000004554482d39000000000000000000000000000000000000000000000000000000000000000000008000000013057cc4000000000000000000000000000000000046494c2d3700000000000000000000000000000000000000000000000000000000000000000000800000000a54a0ae00000000000000000000000000000000004943502d37000000000000000000000000000000000000000000000000000000000000000000007ffffffff28bc5a500000000000000000000000000000000004c494e4b2d370000000000000000000000000000000000000000000000000000000000000000008000000006f1808900000000000000000000000000000000004c54432d38000000000000000000000000000000000000000000000000000000000000000000007ffffffff878330f00000000000000000000000000000000004c554e412d36000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000004d415449432d3600000000000000000000000000000000000000000000000000000000000000007fffffffec6e3be400000000000000000000000000000000004d4b522d3900000000000000000000000000000000000000000000000000000000000000000000800000000cae2fe700000000000000000000000000000000004e4541522d36000000000000000000000000000000000000000000000000000000000000000000800000001f44b582000000000000000000000000000000000052554e452d3600000000000000000000000000000000000000000000000000000000000000000080000000033af20f0000000000000000000000000000000000534e582d37000000000000000000000000000000000000000000000000000000000000000000007ffffffffb30f34d000000", - "0x02f93575058305c8588459682f008504a817c8008353ec6094223edee99c943783a59d0b6e98302b7bd4a6cc3880b935049b3b76cc00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000002f8000000000000000000000000000000000000000000000000000000000000030a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000168686da01a91349036eb9a64aa36075c2fb88d509c000000000000000000000000523f56158e4b5123eacfd0fd0521c9c8a8e3f308000000000000000000000000dcb80c324342dbac314e0d6d70ed25b575789e27000000000000000000000000032371cc2059e4bec142d2b02a25193c571c0f4cf5ccc77fcd5fc208f25af69400e1a4c5836e206d181a0d1d101a774f987f8b7b9afcf2e327ea91fac3e04286061a36f169223983c58f4680c1d72524ed9d540d653caaafcd983dace71a6dd30267e5f5a5fd9cb461ae4182e3faef5e9d6086bb6890650051e91e7bc85bf1b2032c44884a2a49afdbddbc726322423bfb99deb89501733c752413f4a5ae50c906e8c434b1627ec01166ef37bd76c9a1c5df2a91a25ef319be312a3f8e5c4f6206b5ca90e586e0efd8b6e74913711e52dc9226bacadae4964018dc156e75878400eb8506f8e1338b5c543c3fa06ee1d4e86fe64781c3bbc857acc99cb1bdbbb9031e53126ce9f73ccae2f4115676df4d9369c2e93694046bf0ae2343b9d325b7015be3f49dd1fb6f970eaf96520a925f433cb67b9f59bb6ff6f1b3ce205c745501fe7315d4446c9fe0160fac314f07d7ac308d9f7802a33e31021fe10bc6463b06747b446cc3a7cda88193befe4f4cf1d6485505f05ebb84dce4020f8b9e06f0009a2552f0bcd4d73dcdb0d85735a66c302997f3842d421bc706ad620115e3db065ad74d8d9d2a4598a65b537de2d5bceb653bf06bf753af2a27f0b32263de0f0318adfbe9c1485e648f5968701fd775431eaecb53feda886e9b4bef6e5e13a603f42af3a3a203f4e93160c2fa248230aeb653309d5b30fc0ed18a355621bf1307257a723b1576c1ba6d5e1996dac83a903a6d609356cc0f617422dfb0bd753a03f5acea77508ab050656494a26312df4c9c025e881f53e42cead31ee47a9f2802bf073a9d123a1df1995fd380a897d80fcac31f9ed89fbe3937b0e41d5c63b903671de9822bbdb7bc0f0fba88fd1007f9ea94c96ba50114c42214bfb885ff4b078e077f9b83ee2df24920169a8b70c7385e10c61066b9925260761fa989ebdd01fdffd3da05149394a7ea02f6144921251dfd0a9e82bde5679249f85f48af0707f04aec2963d8b5ee64423eb52ef9aec3c39a1180be4b2ec78902b023b0537801ffd71e3bc468059a7a3fb26d1e26c5085ddcbecc21e01b81864e470ff4e0a406a767c7e4525a082af2d22066bbb5abf6300d991dcc9c4413af2aad1756d830019e3a5c639465f2c34e895e4062f1c6a58371248152cd02bade7c542116e889003033970d0cf8a9100ca06e989820299dedef2e408cbfaa4bb4064c5c1a568c04c468268382b55be26237c06ab7c57aa66ad50ab6e00d21c94a8a0ea366172e02ae63eff3c2110db4106296f47368ac0ef5dbf21b410547ed92bafa4c0772940305f4a6df3d51e2b9725b2a542ec41d4e4ccb716cd5e04bd31e65b3b65d386200d8f20b8892098af2667c064199edb08e557fe6451b28eef5e59d50b45ae01b0586384f7cdac8b60d7e46ed39656ca048f7a1c00fa3b3844e0aebf851db611503094f96372deab71598635e27c76f7400984dd9ee8f70921aadb40ea6e3ecd10553cb7cf6061143d3009c8b141b9af86dfb241608e737b4f3446eabb37cb71502e3039c07d0e51efba1902275e89e9aad04b9b71fa271f86bf88a86da08a3c3063c74be6920659fb280bd6dcc3af5bdb5d04125a65a36914b95dd09de4a0aef046a98a11c636ca9e2281790c9a90a142a1ee18b29f8f515780e354fded499f70611b52ac102ed92c96147daf2de5acd8ac018c02040188fe08ee975e707332904f4aeee894143f587fa434cc1a5bb94e65b8b9630eac6bcce03980ebf72b5a702dd07", - "0x02f94055058305c8598459682f008504a817c8008353ec6094fe76edf35648cc733d57200646cb1dc63d05462f80b93fe4538f940600000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000003f6000000000000000000000000000000000000000000000000000000000000001f80353fd45164ddc943332669b8d4743fce7ef1d1cf7dd820b669e98825f96997c000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000031494e43482d37000000000000000005cab5ba3db5941c6ce588b25dc6c9adb565d805629b2e4dd8e7fe6eeac303c10000000000000000000000000000000000414156452d38000000000000000000006e98c93ee9a4e7cc5c44d190f4d3dd08658428a4fdafeeca077a955ac6120d00000000000000000000000000000000004144412d36000000000000000000000590e0c79a3dde450452874a192b6f0c59a3c91b16bfe88fbb6116ee491d5b080000000000000000000000000000000000414c43582d3800000000000000000007acd949642dafa291ed327e123b50cf0dda9fc7a16fc655394e40b6c5f73e330000000000000000000000000000000000414c474f2d36000000000000000000053ffd8fca658ef8a853379eaf490ef3ade15f183a4fc816bab2edd083d182960000000000000000000000000000000000414c5048412d3500000000000000000652fa7c13c1696f321ef246dd4308a122ada7e7c0b04a6159e19e77fefd5a1f00000000000000000000000000000000004150452d370000000000000000000000181cb4081b256dbb6b067ef6668b8ff93d51493a4a738cb464ef02209e9484000000000000000000000000000000000041522d3700000000000000000000000031909be371a6eb458fa5971c19a496efc30ccc069b415abd23a986087aae36000000000000000000000000000000000041544f4d2d37000000000000000000004bd17f89c4545f80ca5f5138deaf412df9e1ed240bb16532ca7ca63496022f0000000000000000000000000000000000415641582d3700000000000000000005af1ade8046fb4cdd050494861b140fcc6d1966bfef56f8c050005e05b34cf600000000000000000000000000000000004158532d370000000000000000000000dc0f4ffbfd73f75013e59ea8197012db4de5f2c2dbb445bec1b8110a91ff63000000000000000000000000000000000042414c2d370000000000000000000002df2bc73e267940de23663550ae40e2ab04829cae6b3bf1ea47c7f3da449c8f00000000000000000000000000000000004241542d350000000000000000000004699da57bd2cad90fffbcd450dbc551b03a1d0659c2a18e967cd3ad5bbb148a00000000000000000000000000000000004243482d380000000000000000000007162a67b6de914bc616e250087be4f4b32f1091173a9715ed529bf49fadc32f0000000000000000000000000000000000424e422d3800000000000000000000046d4c5002da65edf23fc3f276ae8faed3b12bb5152a628a504217dc14e206170000000000000000000000000000000000424e542d3600000000000000000000012307627fd75b93d85a5bf1b131c3f04fe06e2dd1d42e0f69ded501d0b2383b00000000000000000000000000000000004254432d3130000000000000000000032d88804c27889bc102b55175e470c702c5271d4f47ee65609be48cd12ce92b000000000000000000000000000000000043454c4f2d36000000000000000000071925580daa4d3f23f23a8d6eadb8433d4d97f2d8a951fafd467e6ef58805e70000000000000000000000000000000000434f4d502d38000000000000000000063d090b8ae4062273bd544a98a30a8ee7be7884ce7cdc8ca4c76126cd19f4e400000000000000000000000000000000004352562d360000000000000000000007bfbb5c5cb2a8fd2315b19610cbadc839675cff0d07d90bbb38df585ad4a9910000000000000000000000000000000000444f444f2d3600000000000000000007872ede04c06042cdde553e4786f0190d1c0fda22c7122aafdc72786fa8565f0000000000000000000000000000000000444f47452d350000000000000000000566ed4ec703e17aef519a33b94b4b3f68539c78eed4f379a60214956c1f64360000000000000000000000000000000000444f542d370000000000000000000005ff2995ee5ead55d78716aeccd62bea78617c17ddfe3804f75e7a392e43a73c00000000000000000000000000000000004450492d38000000000000000000000627ea347822b38617158da472ba9e0d9ddc72ba373687e9721fbf5b5ebbc3810000000000000000000000000000000000454e4a2d3600000000000000000000010ff91bca840bcbd139cb2b00460f43f7a05c6cc5055ecd935d6a5693e29fd50000000000000000000000000000000000454e532d3700000000000000000000079ea2b418225dc558746a181f974c3f6148d586d53e776f1d050560ddabf0780000000000000000000000000000000000454f532d360000000000000000000006333c241da9571347aa61fd8e17504222087149377c2bebd4d9e985b4627ef600000000000000000000000000000000004554432d370000000000000000000006b126954fdfc445cc6c1b5cc993fa024f97413c4c5a4efaad6dcc5f35facc8000000000000000000000000000000000004554482d390000000000000000000004396e", - "0x02f92af5058305c85a8459682f008504a817c8008353ec60947a7f6d1512ca406cb132e52fe8d38a3ad7c14fcb80b92a843fe317a600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000002760000000000000000000000000000000000000000000000000000000000000001eb7d68efc02a2140e273c053275c0687f3e196fba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000136b19af520bdb27e7e997027c8f3e0bfc12d639943000000000000000000000000645313695b2e971255c86806c9d9bacc97f7dacb000000000000000000000000d3ac49826b956c8383bf5eb598880a49932727f2000000000000000000000000d8c4c7e908cb1a64b21d32c51cfd773e4b6e11af0000000000000000000000007b3829c74146416ac818d393ea62a0bc86130370000000000000000000000000a60d378d832a447379d7bef0d8acc1a4ea9c4912000000000000000000000000b46a4f461bea202d7599afec54f9d4ccbabfbcec0000000000000000000000006ddb93e67f6b4ce03f1f387d6781ef657ff8bcc00000000000000000000000005c680682d111a7cd34c16318da75b35422bcbdf600000000000000000000000082dd7de67b395b955a162bbef760345f8912eb6c000000000000000000000000cf9fc5ae47c1cd191b1a7a18dc9e0be2301bad430000000000000000000000004c769ffe431119d5eaeb8d0215cf3cef02546516000000000000000000000000274f8689df5179f77a4424fbfa6f34e52184325a000000000000000000000000ac1e0202c9db91f6716b5316951dcd4a481ae587000000000000000000000000052a778b0eb7b04ee839731e081ec4f4e72077bd000000000000000000000000792a108065f17e09d526637d19c6d47e3237cc0f0000000000000000000000005aef695f2f64f2e9b0ff02fa7261c2adae7f7c69000000000000000000000000a53cd9f85c6583948f93a4fff9e4a2d0fae4bd9d000000000000000000000000b024db6d253bb1182f2178d4d81c6f16d8c2287d0000000000000000000000002a2c9b0b33c502ff1972e5c55cbcd695348e37d0000000000000000000000000e6105398b6293b9eb45dfff7fbdde63188a93981000000000000000000000000ed63c3d2cd1ef0fdd747127de25cd545c0def7ff0000000000000000000000002762384f5603366551a811022f786d32bbd7f4900000000000000000000000004d643900ba5a0e13b7f802cd1f04cf7ac4522156000000000000000000000000e7e7b2cb7a38fb07b1da63e1398b99eeaa6aa028000000000000000000000000b86f8f5f17ae5fceea279dab490f90573470bc61000000000000000000000000982734b05239b49ecec796d774df61a1864d608600000000000000000000000055f6d9301886e91129bf5e576fb678c0ca96b3d800000000000000000000000076586cb17dc63510e7c35b971f917f4be7f5c75c0000000000000000000000003654f65ddf4ea6817d1de5749350b54ef503630f000000000000000000000000969106e29ca905254e861f6df03c0377d07f26710000000000000000000000000bf4a6b5c04220159bf4a597862157629135d3c500000000000000000000000030b330f08c494ccf4fe6e32638634e116e33e38d000000000000000000000000c1a33161a03108f04bfd51ee9d77dcd68a1b8f46000000000000000000000000d4fd17890aefe1f8169440b8f78a31d65ffd2432000000000000000000000000b86197fa1d82f4b6426f0e7b44d9563983bdeebf0000000000000000000000009a68a21892ba70d2ed6806a651680a0e610d1977000000000000000000000000784ac3c918cc7d2f994f0d792d63303c4de64e3f000000000000000000000000ba8e7421d29ab1c675283dfea3a352d62ae5886e00000000000000000000000097d5f3e91c08a4d3e3f0831692f0b20b9ec032190000000000000000000000009f4f3be11ebe14ecbdcb85fe34ddabc2c1051c6a0000000000000000000000001601b381488b45a12a24a3bb750a7908fe610045000000000000000000000000f9a7200b6d7daf5a5e30f63e5fc3e912b1a2fdea00000000000000000000000077e0536e0dfacf7bf305157bb2ba2711d12ad7b50000000000000000000000004a127fcfd18f2d6d87a216a94c8f6d737b617ec0000000000000000000000000dea972b375b866f1ca680abdf9fbb8fc1a5338da00000000000000000000000047318794599801babafec5aff290e864592101130000000000000000000000006097a263f61dfed20eaedde9cbf9b1bf35a1c4c70000000000000000000000002bd7f29d10e92fdcdeea6c8dc18e3d659e9bd923000000000000000000000000a0826c3c53bce48474cd90816de26784c7dd9497000000000000000000000000248176ed4f9e21a20950eb012fec09ed1c63eb070000000000000000000000009c1ebc0beaa91cd7c541dabcbcb068d335df91c100000000000000000000000033dc979771f368e2da9254c323b7b33806d9baf2000000000000000000000000f6864df3c201dccb89c9c753a19eb73e75ac9082000000000000000000000000c491242175483a9b7ccfd3b98c90700d7fa56ba4000000000000000000000000731c3c41451b1c9c66adb76801e4fb384660e16f0000000000000000000000001eb72a243c38ce58f17a320295f751a0606c94fd000000000000000000000000ba1d73", - "0x02f92af5058305c85b8459682f008504a817c8008353ec60947a7f6d1512ca406cb132e52fe8d38a3ad7c14fcb80b92a843fe317a600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000002760000000000000000000000000000000000000000000000000000000000000001e1cd5026339e94719ecea3e5dda7eb7c7abbf110c000000000000000000000000000000000000000000000000000000000000000000000000000000000000013603f15985493b726bc6fb6b9235e302334f8128e28db5926c0a00a645662eeb2500acb02c24ea0e10ee1100fede5a824f46fa9c34172148ec6a754d57b6b0b3590267b4242a411df735deeeac9480d3796ceaa6445c3c2932b124c63c44dbc1ce0619a17cb6f94d81edea1d05c3ad618cffa473a5be78776cb5ab5235367506cf05b792da9608f9bb98b7b8d641cb6211df26d68ac72fd0277941f1e530eea5d805170d30df77f3eee4020f3b5ebee82e1938dac64783a2c2ac6aec0d2186716a07e7237b65cc5ba5440d9d707fac679ce5f03780dcf980b779c2c7debfbae461055045c587550d734c2f8084c4cd2ff81c9fdcfa7a5bb6738119832e233795ed04c23eb90a6a8d6a82adc6b8e943ea55049d56ddf990eb02d7ac10ae3fdbdf84035ae4fd5396027f096346d5e85ebc65f5a1f72ee81457b87461aeecaa6a523607260afa417c90d8bdc2256892ccb104413e5e1c65a3030421fbe3d3d0953186032827ff3a8c2cb3dbaad31f089de2283b0bd04e8dfe0cfc02405ecb413d2dc0b7ed14bb0d0020dc0c2192c69ec84e8b2895333800000000000000000000000072af07c3cedd321a964a181d0c55d983458d805c00000000000000000000000058a10bac1df6bfacdaa890c22705a53ab805172300000000000000000000000071c2c083cac14ebbe1760149095be60d9c127a50000000000000000000000000a1f9e069ad0d6494ceab4e82ffee0e56325aa438000000000000000000000000447010b782c052d29a08e3bf811677b72828b0ee0000000000000000000000006143ca8081dbd00de74eafc3df334542651b7f510000000000000000000000001828be8542e16cffdaad1de9b0d4fe1950a0550000000000000000000000000053a6418aec94ef4a5ae8dbff2653fdcd23629950000000000000000000000000401895e6188a7c6e2c1df8c3028aa12809a9f736000000000000000000000000e18e0ab827aeb590a1f93a86387cb1ea8630ff2a000000000000000000000000a21181669d0a269b4007c30140e57774808aac91000000000000000000000000b31708a4030bbf7ae74da5a214b8d2f365ace8f100000000000000000000000022e37a6e3e361879793e79420cba8112795006130000000000000000000000001ae9517c3190a3d0141eb3dfa1c20f6f977a4b0b0000000000000000000000001c6077ff61469ea4e65e6b15b887e831b9c97ce3000000000000000000000000e2094fb872833e2462ed726c1cd08d5da2bbb88400000000000000000000000024fb922fdbce46e246de2ac644aa2247aeae3f7d0000000000000000000000002ac5730e3db26ed489fc718fd9192d236c01d113000000000000000000000000f6c7fdbb82dba1b5a73c3f08f3974bdba799053700000000000000000000000072386d60e149c46193dc3680b986c45dc997b7380000000000000000000000009ec69396df6d09c1836118b43cff303003c0a3d7000000000000000000000000b66f2b7bf657c7cedc054f7ccd70c343040a7a27000000000000000000000000f2d62a5c4b802535429db4f51cf721ac7f2cbe5b0000000000000000000000004464b96279aa9c9fbbb40a123c4e7baeae104c960000000000000000000000002b1e1ee908de7c7388980860d2e319e1364673a0000000000000000000000000cf44a34918d5c4f427ea13f587e60399e9582aa50000000000000000000000006b6e1fe53da79ad5b190648734ec8a54e6172b9100000000000000000000000072fa3426821c21d690ffe1a0ecb698e3c4e096cd000000000000000000000000f149a4bf25313c749ffa6fbc9cd007084f6b60c4000000000000000000000000bacd652e7204d5e6ebc53287eba0741014fb8f6c000000000000000000000000cee7f7e704132866fdaebd4c0c4f223da5bd96c5000000000000000000000000dcde6a784dc8f4d6958e166e104d990155b993590000000000000000000000005ea7cb70a003d4626ff0a91fa2a143107a1370840000000000000000000000005fbbdab6f0172b7fe346ebf6054691eb21c67405000000000000000000000000e84c9dfebf04c6a7623fc789ed34581d26b3086b000000000000000000000000ca29863a35849bc6ecaf3d65b21b87e3c68b3ee3000000000000000000000000412345bf1b0682852e2537cb3b659f01d8d689210000000000000000000000007a6821cf3a25c58204e6791289f50c8edd44482d00000000000000000000000026418edd2bafeb0f5ddb785ad97d610e75c819d6000000000000000000000000e5ce4bfccb2134a07f30bb41e69deeb9e3c8bb220000000000000000000000004cd8b41de1aa2a8615f1a0ca5909bc57ff33d5f70000000000000000000000006143224bc5132d1a2aea9eca08873baa9abb5b620000000000000000000000000514171d8c7c4f70ef7ab40a0f0cfe46bad563490000000000000000000000009ed09743921dd9773b72bed9b9692490f3ab15bb000000000000000000000000c84d71", - "0x02f92af5058305c85c8459682f008504a817c8008353ec60947a7f6d1512ca406cb132e52fe8d38a3ad7c14fcb80b92a843fe317a600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000002760000000000000000000000000000000000000000000000000000000000000001e0cb95d9fead5e9dacc4d4898956e3d7062baae97000000000000000000000000000000000000000000000000000000000000000000000000000000000000013612bb3690f781782693f24df908bca67814c3f85c000000000000000000000000ffbcea269917c9b61acd951cca931d7dd2963d300000000000000000000000003b79aa0645d97d1f508cae8bbc3b919653e57ae300000000000000000000000071b9a212abc156a0f32c34025cb1b4cab81cab80000000000000000000000000a7146be486deab1379b193b34e131b34731047270000000000000000000000002e24f24dd384d80f0ecf85c08278bf076aeba6cf000000000000000000000000169bf9277fdd84e3c3f886bf0075942a5792b9a10000000000000000000000007c9776bbe841a1ad24855d53d1e3f284d4468c9c0000000000000000000000008c96dc8321f7b7f98fa09dd15d8dbeb645a3edee0000000000000000000000004c8bbf92a27aa299aa9160b112b72b551dc9bf350000000000000000000000000aeb865d36e43beed953d26c58169ea1c4cbb1b0000000000000000000000000c59245ea1b0424f4e7d7cba92f7c0ef746e0ff9f0000000000000000000000006bf3c3e065f480407dbda50db4b93c146b6bcf9000000000000000000000000013b74951662654446b62326d6b0997ee0221435d0000000000000000000000008aedb8c10bc5b05ec961a139fa0304e067bea5550000000000000000000000004faca2a8d3d81482cf51885cb3afae5477fb2a420000000000000000000000006466ee2e9e9c17f76db754b5f21f0e79c71567330000000000000000000000003a772454c58bb5a73a5078ce7ddf69efa19af5ab000000000000000000000000d6f8ed30b54cffb7cf91de33ca5bbd8b585a7a1c0000000000000000000000004a02f7b782e4fd7ae50f8c48cbdb985aa3088b0b00000000000000000000000043aa712e06c66a62cc9816ee0ee658fbeb50b96000000000000000000000000023158dc5adea2787c9b1248d4ee480c900adc0090000000000000000000000003e11ed0813839198ee3ba1d3366433146d862c7e0000000000000000000000001ded22c0642a88c0f566f7f64345b6d988ffa3c1000000000000000000000000e8348cae9bf1a470cd98988710849faaf261d2560000000000000000000000005df75f3b0f8ba6e496a2f96e266ad9e0e3eb0ae400000000000000000000000008defaf0ade552c9e87711b448071b07c051bf3d000000000000000000000000738dc7a068519172fba1ec750d59fd3f433611810000000000000000000000002076081d1cda092ff7492760912e5841398b9d370000000000000000000000001f96c8767a3a082587548244f4fab67904ddd2b300000000000000000000000053484761d279f86ce167994fd886dc264fd9dc680000000000000000000000009095c6492f6ef9120dfad7f1c081958203d9cf4f0000000000000000000000005a23653cb3a44ca4f056e4722b5fe0c0575cfc72000000000000000000000000ab7fbf32862a932cdb28b8bc0824f1b4546d1976000000000000000000000000bc4817f28699d928e9490dac2a494f11ecea5ba30000000000000000000000005171521538bb3c73aa5066c3bac7f969faec3573000000000000000000000000c1410ca1ea6f53b8fab97cffc2bc0f93c4a4439d0000000000000000000000000401b26feed11e5a1acf1840c91923bc8564afff000000000000000000000000a68aaf58ac97dfed3d4bfa32295e7b5efafea6ca000000000000000000000000f25473f83a28fe7e7cc70e70173051ce0e62663e000000000000000000000000daf9e0081af0af2369eed1d49818c6da2b9ba180000000000000000000000000914fb98ecf0788c902edc8fb73cb34847ec9d87c000000000000000000000000343b492f581cca47889080f60f5c988bcec92e6d000000000000000000000000414230eb2f84649b46b9a493aeaf1561cc25e30c00000000000000000000000092b70ec4ab3ef53eed56b2fe7204e7447e375905000000000000000000000000a740a2a83a3fa4ba2babcabda0ec6ee974ded71f000000000000000000000000313777654ad6856736b6e85c8814fb3479641c510000000000000000000000001471e12e619caa79bf3bfb4326541d36e579bf30000000000000000000000000c2e13cecabd3df8f2ae522f5e2694efe0c00720100000000000000000000000066ae5753f7222247f8650ca0cd8c5fd52467c72d000000000000000000000000667affa88b2e9785205fd4f354b90a895805b1d90000000000000000000000000f5aefc0c5cbaf408b80c4ca954fd7670601ba020000000000000000000000000d5725723049bcf05abfff6188964a66bdd6b4600000000000000000000000005c689c1556c575526f156084c3af54b3d1070aac000000000000000000000000caceda5eb6b5ce8056a67f88770b240c0365c59e000000000000000000000000c953b9fe172587bf556197f18dcc0b9e02d1f25100000000000000000000000050045c4f7a73be883391b9c9bdec57254aadbd66000000000000000000000000c9952b", - "0x02f932b5058305c85d8459682f008504a817c8008353ec6094b6379a14b9cbf8d7a5d98db05792c5f01326da7b80b93244e85a6a2800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000002d8006460763db9ac72c2f2b50fdace40ce639a8a5a7a8f3448d0ef0222f13552e1800000000000000000000000000000000000000000000000000000000000000039986e1abf0e85466243ebf41c6ebd6742dd202eb000000000000000000000000000000000000000000000000000000000000000000000000000000000000016601a379b7faae52bd5d99f8215c4daf532459da7d44827775d7df34544b6f4f96051e0b8b80b8119ed29bc8cd6e581b65181041dc29bc3ef3d64b4dda19ccfaa603a2d65e441d338af9ae5fa08d8de3b84e812710db8cd73f8818a9e019d7cf3003a53f00c37f0577262aa9bcdd6c0f0be55dacdbb396c181a8a627536989a069019409c4f7100fb2ecc690a5e0fc498ac45e3f189eb79c9c545ffe07083dbaff02f3d3ea3ef6e8b93f7858bbcf22d2f0418de3f62aecbc3f494a38d1d692924705ea42b84542a37c0dddca63c8a88522c5ff567b1970d006a26c098c3c1bd4f307f213f3e9449f720059484b2158e18fc3dc6725964b29554c23e13c0ba71e9c05f1b5ec75ab67620dd9fb0e78933a20fa8f13bf2ce0b0ddfde58888a7320bca06ebbc67ff22d63706a24c2f682716a7d5c67c153a256242b0584765899ed01202ccb21da783f451488e79930235cf21211bdf4ada182f97b11f933adf1417b107676e141554969419964298389d5e37fd07ba2215b6e6bc2de71c54e0dce5ca041abd3e326827bfb89065b494704a96aec5b500de3bff205ac71ba3d2fc7ccc002b6984c53a0d19573242eb8ffcdce31efd9e086e047f5fada39cf5e9ada1940116e464b0ebdfc16d86c34703b003f19f87ee2c5cce0d6bfd91766fe0e50d650164ece0a91790d69a88d69c66dc26c41da9800446e76ecf8cf7c12f78201c7407c191f592da1f91eceb5731423eaa7b5dafd69d7a68a302629e6b6836bf3d07029374cd2d202d7e6c068ba2c11160db86781958252f176f36b9073288c9a70200146fe5b9ab9cb7c85902c79a5aab8cc627c3ce95293d0f9317bac108f43b2403c15d5cc60bc572079f83aee1236c97baee5a84eed623bab93da9d667b75d5f00ff0e48cc2b6de0464ced2a17a32f8fe47d6387b3eb929dc33b7bed335869d602f1d09dd5b907a63f7ae972fef3204136b963f4c84c9e85bc303461cd21798a0771f5f46e1cc99818ec3df8e949dd01b22ffc195999ac6aec96c4cfbb0dd7c803318c49d79fd9ac92f171243989372d947816693a9f80a44907c6ec0a5c1b7c07b2b2118c482e220a44489009bcd8b8dcea5dc3518b052d43d5f1050679ccf403162b2e1d7f91fdc216da72b08c6c3a866761d1e12b0bc3fbf3d8e47949c4900441a58b0580eddeb6fe0331511a637549c2aa930d3c27f04d515111a54501db06b4b538bd307ae3cce6377f552272d4c30265e039486b106230dc6f1cc6f15b00a3811123a29975ad046357b4488d5754b5e0bedb8c4569e6fc6f31368ee4f2044bce11791bc5872d938c1868e8768edc73f839690bf3e66b568ccff46f63c107b80829904390ee6ebb054e0d3057779f11bd1ed1dbff08e513ffcd7ca8f742032419cc994c42367efe45c2b42d6cc4c3391231fed50c02c42d957414f5d16700f7e63f52294825d5f22c53f8463ab74d1204cce19c8de1e4669326ee1fd8fd0169fb72a1f89e4e412f57d0aa2482a56e426cc42a0463f525292a4b9423c50807232c80aaa587251e505f30b703990b84a9acf0237f56707a0a89b740826d1205482b322e3515aae609f5885285689efa94d5237293c6faa760e8f4647c2322065d8b346f3ab4db7352a426170330a86a1b58f69ce47519179dcbb24b29be88056c0a1fc760f5c25ee1084dfee007bf159cf0addd214b33559b1a617dd4351105544697814a09fad13003e7beed9267b35d16513570b952ea18a970c994e78603ee7973fae188555c179b506041b5ba7fc56d9de363c6a03e3f4fe07e662a2602a08e179f1f50e4e02765e207e2bd412a97a67243ca477776580120f9c810ad0039e6ffd0bd912897e032b8077a428a4d75c1f0077f371e249827d5963881110155ab8f7dfed95056ec08afe4319e401d0278a80d230cbb12387eb9a5439ae9048af7cba37bcd67cac01c84c5b1ef6aa1a7fa49cacb6d011404637cfc2527a80621e2b38f83caa48a50c62abdb20637c7b6a945390f36b3172c8dbb5a2d20e3027c3297fa7a4354c89bc515ab908ceef4c648a46ce43173ed4139566066f15e060703217ab1c63f5f7157e10225ffe43ef33dd96c92826395511cfce706a05000d5d8467396f9b4540763162de6d76f1ed15f4a14bdb62456ed9e3556d71835012f7459d397c39727476c1743355119d5d6b273378f02edab397f0affac855d018af99871f1a81ff289619f40a09d15d171d4d761d8a7200c6d8cd48ebf6fc20055b61b9170005b53db72dac6a3b7a7a96150eb9f739809b61cb7c5df49020901ad9989de4c742e0567b6ae87ded7a6ff3df160a1a838012d6e78a7f4392e6204c24d1fe71fd3e37ead79137ac3996ca5079ab6dfebbde84f451c4de9283bfa023c493fcfcb62411f0e1c3125e86e25af6e92f5f34706fda9f06b6d147a620f033189308cfc9559a2db9c6cccfec3588ce6acd696b63d984f955e25f0d808fe0317a8bb9a2b758dc8dc6c2d3a481dfa7fadc8ead28240f5a6a6ba6fe1ec71480599ed", - "0x02f92e35058305c85e8459682f008504a817c8008353ec6094b6379a14b9cbf8d7a5d98db05792c5f01326da7b80b92dc4e85a6a2800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000002900059f6c72ee5ce1b2b9c73e7d388dffa93986a4049dc22f913e0c479f6c8bd3430000000000000000000000000000000000000000000000000000000000000003a790f058179d789827ddb24b18e7df50b2d27e54000000000000000000000000000000000000000000000000000000000000000000000000000000000000014200d81133f7072f9de7be316cb37295c7d7e0b99acb7ade87ea33d4fdfd92733501170bf3dd696f071b6ebb02cb748b471b435a2a705c13f52e1d88644d6f06d70223a176a28399e389f2c209914516ad5c5f9915bd75c7dbb22c39f0f76abab40661700fd6cbf626a837641052d54e311aa580d79bc48742f4536f53b2276a74060969c8e1833a1ef458024c0b4d282ef543e69974dde33035b3f90fd06d5dca031aadba1b435ad947af792c22c524226439fb7bc50361984f234571cd589c7d034e7d5e4ce4ae618ddcbfbdd664421917a276a66dd56a27312c0b9041c5591500fc2795bd95f370942290cf8b482f23bb9459d3d80308d801692bbac02f346901dfc0d89d1b5fe5b947dc7569cb09240e78b574f10762f7c53dffffd01abb26024327949f95379195caa142d6838ca7cf6b7b69a68991ba9d71a1f48c4514ef060d455929180ea7a40ac539a0f29f8bef1d1eb5c6de39348756549cab8de7b5010009a9791f063f1ba178babe1bfa274eafb3beeb4ce4692123b1bf12faf9c804bdd2dade38fb87f37ced539fd3bfb405f7057dfbb5c562028bf62af41458fd0749c4183398789153c47c8f1d43286d872426636624c123e31ea98e52bc56e7006e12fccefccab3acd7d80588b0d4e732a094ea8227dee98d1ba0926cec264806cf993ac8d78b6f6d71d0cb36a5933fd356f92e6bf84661fc524688ae0bed8e03d5bb61fb0dc1a02c8d4b3216df3d9806dde09d1ab71f909858ebe068be522c038ea3691f7e10a44d18532689aa7567fe64fb782e75cc7641a4295e0372cc4a00b0e41f4a48490d633aa6c6d453ec6619b27627ff5dc7a36e30b20dcbb670ad04842b5c556c46075328501b7aec46351c1f2233af413c3c055b0cbf5100139b0457088d5276c2d4c253f13c6756634cf6850bacbe68ba15682d8910208eb39701de7d26e6e9a2e2a770d14de1f4ae2bb2374fd4ea8c1b5bafb3400fa877a04600fb0a3e92060cd7c093225e2bd4d77bc40a3c8cf8eefec2230ae5b0f336927205795bf1e37ef50a30d362046c010ea76e3ed18cd21b1212fa4dda384c62b4370608a48ded70b47514e77a6c55565a8985b4c1f33cfbaf2d095e91d8090b4e3b040ccd36736a440eb1d930d0baf5a347bb67ea76e8557ecb2c992d78dba579ae06d97762d29a28319a7bbbccc7934e03e17664b5e21276db71ad24d99b6591f7046b1ebf2317465da2660e1b521cf2eb2231d3001c7cec431c0a2af892fc07e70346ed04e4007596ef048aeeb29d7d39c3086f1c229a9f428573861f2d2917e405ef78afe77d0bc2d4f1b9f35f2238e50a5dd4e8775055812d43150efb19e31303a0765483615d563cfd4b5e8f0750965ddcdba560b71b4bf8faaa08606731e306c1ca5ca2fe40eaab84f489fc4353af3cc10a1edfad5fd48769d8f16a9616f3054c956fd58e59099f44a15174964017a5b3e1022ba5da7e41b0e97aac21be23010464230f603c2d33ecd610801c0cfd286ade2a788e95e054d53c3c9ffad0290787d8bff19beea52b3ca272cc043395ffb0f251a7e589e10f0a1e7be5bdde2400617e4a9e47306a09a9485db24f2bf0240cdfcf490d2872fc86d52f6f88472d038a217fe936e5fd8ae69e283e3f469d7dd5b36f5746ed5ebff7f20f2c52ab8e008aba06edce9340ef4ab2a67c3d2e4695bd3ee5427e2e5c9e15dc069c8280f700d12c476fb95dca1d51e8a4f2f6d6f22cdb3c978cd5be8ddbbaa65c4acd1220019e53f5763fb8d0290d400caad0b600e3cc1979770ee75a9f5622fc02087504078f4ed52403e127e22b655118501343b367125541edb607a7a549f9d7f11dfa001bb0ae9b0d90499d277a089c2fe345ab13d82a9f7d28b6f809a6ad7e1f82aa028545ca6684e34343ea8589d0bc8e1889ac0b16680dc7c93b8f91b9bd610f02048537a7ab32eba351cb191f470af0a338e2fbd71e35130925941265aad4c51f02008f0e8e0b8da9ad369a1818be94598f6fcce43b9b263d7268ef9dfcaf7b9e01d2ea2b406d36a4bdc6204ccd1930ca1be108aea5ac52df9f8c94c32ef7bd0b01c6c97b53e53f531c5be54513b3f5622b9e4e18e1f267851c017d035a52025f0708e1a4e1c1a4091b911492975da601b80ac6c4df8d0d9f8253433b387eedea0514941adbee5f9f25d4799fb0a6df743afa05e01ab02597a604c5e7a70e85130030f5eecc526fccdcc7b0d828122c169bd365be2eba1fe4380af32609bf821e010dbd9dd1f355b2e26229fdfd3a4c9e876e84d8783630f4fd27667374aa41d0017b02e89fce64bf090041fee5284a5e88d1345120dcb4f7116531cd101a8522033a7930e5c81697a747ee9d765197b45bc38527f058a1ddc3f0177f9b47d02004585399aed85e8ed5b45f0747f723f8605dd2a74c90f6610f98d955cb5c32cb001b8388468f16b8ed3a2c324c65603217204c07fc7c5bf76a4a32373c867440034156d32e88b2f6c9557b6ab5fed0dd888a8faa251dbf095e00c5d00b42243103cfab", - "0x02f929b5058305c85f8459682f008504a817c8008353ec6094b6379a14b9cbf8d7a5d98db05792c5f01326da7b80b92944e85a6a2800000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000248005b02367334a5ffe4f054568042517fa0cef82bda2f6f7738718c9f825d8c4fe00000000000000000000000000000000000000000000000000000000000000030e9e685e9ed3807ec2a0d42cfb97339720502b18000000000000000000000000000000000000000000000000000000000000000000000000000000000000011e07d0f4af005ec932fe77bfc369b38f106c8c843cf49e05c91fca9353c60b32c4006c67e913a359e026d606006daf1945d67f46a02399cf2fa586c3f09c16e4a8030a567be12a371cdce9ceeafa699f215f6732768c79e0fe607a92b6b4131b31032cb6df1ced02be0c7655bdd1a87f94ba5572b3a86c29254fc5739b613e2816043856a434027dc742074ee34615fa1b17a31ea527e67adda9cb342103f02c29068275041b5b5c92227fb0d0308f4371a8c95a16da5c841696da342408588c9f0189fe4da42b465f607cd79f88d71ab19c45fa169f3863065079420c5e74ac20061e6e901c94aaf229640bcad281c3b8ca767c7795e97efbebf1dbdfec9db9dd0258e71c8db8b33f6f8f7bd71bce26a248052531387983f6244a006fc5b732f602ac080b889d1b406518b6672eae811d775ab01506151a774dd016f80da5ece503510512243a9f796a0c9950f46eb339ae7d2b4549cc72b8517a85c64f27d2de06d25b97fe8ecb391c9fecf95247d09a277a1cf52918eac88ea06ed864e128bb004f082b6f981dc9ba95dc67e43ae9dbe683fd38e9162e1780a58a432fb0603802bc4a0bb06a599969e6e6eb980cc06ccc31e596a1d60d7ace55c9bac028beec02fbaf9e98ad17f08b2b5dd5ed9767bc423044880ae50585b17edf0bff9a556f07e17bfb2c07c39b579e0b40baf191ab6d5810ec317698f03ac274ba02a4466b06b78199122f0bd640cd369cc086b8e847554671934b0e255a8ac7bbc63fa94e02aae0f3cf62205e122e0baedd04ba6b750c041ba2dc61fb91f1f2988607e65701d694e41cfc2213b2101e64b4ad306860a66f0f1a8f26057e4c735d4dd0c2f804e3d2834fe22f399ff510ca97452d2a351057470e6e8859c8c3a8e32d554738018058062d191e2ca33688fa6559a041b2c3ecc8dc5303dcd210916af8083fbd02db9062812ab5962777e9c08308471203466815049122d3294828ac47548c650637cc629ab8a34eab6bb1ee6a1e5fd82223d12e53ce73d336b72dfdd558b876039264b4af7756f0f24586fedc2a82203934bb72958fbdabf2d3ea972686ada401e900509e9eac0882d00d7fe069eecd76c0550993f759de7e8300892f132e900185b9332378bde62cf2d904e88c9f47b30dd2dee6b8a2b866479f257d5e83c902b3ecdd30a9a2d247f3539bdff03a5c765a2e88f1b3a7a45c5a8c4058ca1e310474e15b05df7af618fd502553c1b82f93df9ff76ee6f68b64410b6308e5d508062f5706229614eb66bd4c9631c5f5941a54a346a567281735be905f3a63c7850789b435ec89e729f8ddcaedc0203cfc29262c67a681322be64f4c960fc8308e078bb32e668d1cd3f7008c740363bf4bbfce632087c9d0fe9c778bebb32b72d302831d3b4978f0a871558d1ad1d1c9727e7bf1e9432bed7423c3051f0fb150ee0715eaa1a41c916fd2ef5d801c5d31dcd5cc1dd451779ef25ce6de34681c25fd019e0ebed03ccb77d6a0f75184ed2aa626b3fb42e68a691ebb58e31aa21d334305347eb9316f422348fca8db7ff225589ec1dbd46eedba9ea04657ec1638d767024a86887134589305c460e1d4f952ab5a5c04e43ae7d691ca908b52caa3f78001caaa11545983677c0d9a75fc8334ffceda930043d6f8bfa93f72e684f8739d067be2137a150285394f8387f89fa845ffed996feea70abb8599b4ccaea3fd9f018c8a9b7bf1c3d703e6a17b9c0665f21ba342627b5bc6dfdb4915ef590f6c4e0218a145f5eae986e049bc671ce8e4e557e671c167067a23368fc267e03459fa07a02f604654d75acba9c68f849c7bfabd395b857a64dedb7d9d6f71b112b50a0661759f2ed2451c3b020a30c1d0e420691f02151efff14a9e88cffbc6b82d8a0454da2c05ab86975070ab807dfb5bfffb392db4eac98b45cf40c2d868f6781f03ce60c2f723d4972276753c9670c19e21fce7ad160a1289a8a26c98beb0b23806632915af610c6b3ebabc942b3c6a1c374b7fd79b33e293a6ac8f2ba107cbdb02ff8f4aebde1a820000577ead1d9c503412f3a2d74b4b39d158f067bc5b27380718696f8ce50ae7af8af5d0a00564c0de99acf25ef5b1f2f454499ac17b657603ae531c23ae4515f1fd49b65d46dd08b0ff5f4606bdf230c83026706d7a218504c68f090c880b2f42c103b7e5a4b771c5c542dff302b49043845cb0af83078e00ae4061251b91ae779e15e5e38b8cb61f66b3deb998f50b0d24beec49ec1dcb063ca20d0565f68b7f05f04a23b48316b89373fd6d9eea233e78f9061891bcaf02462015e00abfa78155ecf08c4ce5e4504598c1ff3996f191f67ada8f8b6348021ae3bb500d78d1a2e24c874113f17d93f3b2b2af7e1cd9873e5d7f50fb69cf0560ace7e5617bd80d3453fe6e32dd558adfeccfa96173acd00b8a12cae739d702a004586f36f8e94cc05a5c1822b7b974a307c025ea8c7fedbdfd308b2f1c7a02fe6b450ab19d6653c49d53ca33be4e693969ff9b9b5292520a6849cfd76c9707a769", - "0x02f92535058305c8608459682f008504a817c8008353ec6094b6379a14b9cbf8d7a5d98db05792c5f01326da7b80b924c4e85a6a2800000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000200001e072e3ba9a7773e1a53bfe18f2e3f790ccf86550cb90a738a60eed241e4d7700000000000000000000000000000000000000000000000000000000000000031ffc6e7bdea215ea5a327e868708bcd1f65e001800000000000000000000000000000000000000000000000000000000000000000000000000000000000000fa05b805a78002eaf459e4327f40018c1bb50c984b62f5f97ee79b35603be43a740095ce72a6086f9df5a8cf5142935dcf643a1987fa4fb09be85edcc4e487c372029b1896117b8f00da39145d4951ca306be14c02d50050c0b33cb7be1c3c2a73004b4020dd817fa810dc4021980d12c333bdbcdc95774b68dfe7900662c009ea019ebb0754eb1eec7cfad07c0ed0b56cd6ed2efc4fd746b7fe353d4619dd1e3c0381fbb14872d2f3093b5301d30dcbac8d069839247c601155f13eafb9a8a619061d8f1c2111b43b3c8be06fb410b92c872f559297c0c484e93bd0e4856e437d01eb537490bacb8440396b59eda1b8d23c81c1707f8379bfc0cf29c16d7cae6b01f2a2c392f86562b9587fd81b7acacc13ed81325159d3d465e069aaa2ac377604805ef71be5782f9989615f3b17de013bac81d178d777fc17f796124ac96fbf0235166ad720116e63f89efeb855543876242223969a6c7c788afbf29a3ed0540554f4aa088f4580d5f96b3d85bcd977e9844dd0a13b3011b7cd504ea81b288602f12cdea33eeadc14688973d82fda4da30366c411a2f43561d6bd6c8b8fd85a05f9ca03a9b4f2bd6f4d9859e0b5545773c6e5f437fa6d42dac33703f2064f5802c8bd873eda09c2a3b6b21c835c107c195434f210a96c80841c361f532966b905bd4bf01ff17cc6df87db3f7b82cd2e26743784a05075c89f1e096d18396e2a0460403362d299513ae278363f695ab045958e0559706ac2c3a329862b384f9700892b30c558d25d6ab2b06e25966853a8123f4d45bbc8d309a82ff3947e668605f8926acb813dfa155138767277550aa3434e9b0eafb9fc1bbf62861ee012d6021ea60c1f0293bc55074361a53d3c68d9372de12a4af749922fbf0a9b5a5d670668f23ab6e346fddf5a6573c2e7db65b7813ba73c7297fb3003b9e28ec8925b017b756cee10ab699c80b7b739ed4e495dc07ca54f6df0e3f0736e27e6c21c7a00925e15580d6ec5cb3b5b9b89c1250256788390cb10dc4ae625a55367ddcbb4005a26b907ca2c23605bf4d6defec40c875c718c6d255b6c5a886775854f513e072194a72e0f368c80e7108c2e51b2b55edec497abfa10e4ce021b354ac4bf2a07434df3497f33276509b1f721531a6bca27f15646fac021fa8c0b116d70e948065518299825d162e14974e8f1c54f1661a7551c3afbf5b3ad54a9b7e26ab09b03d6482d2ca2d083f8415a4aca828d86432f81d8c7159f87837ba7c0018ffc54075f3fa1c4e29312f3253883c5662cbd31f27c245ecf6b62a35fb6be9e99bcd10211f27df6962f292c856952233236a8d0c9901dccfd8392e1b276ab157c065802a6d8e1fb8941ee2d08edf8df98ff67a606831af00b19bd50cbe0c985a7f33f039d50efc8610c0a28e3d58f357abc322bd1d8a69ae9fb31a97931095a5ef41a0798eebac952758ec15246351b7f282c78f0c9b849a0e3bcb118698a81cd2bae07dedc02bb89ad0e390c2fd7b4d8953aabee26bf6a3aa632dcbd175c57f1924306ffb1a303949b3a1a7ace69e58730e38354afe03a30f9a9f90cebecedbb8a8e00cfbcc6640753a371c4d4d4382a8a0a5ad7b8c9039e45302f13a18b591e811f058854ff4b6a4430307abfa7ed6647d178d9ae689cc20a33d0659897e7a3efe4015746673118f3742df08cf01f71f92266593776dcee27d286931642eb62b702069fb2cb85ac25816595606faa8b9adc8d68b678aae8b6c487e60f816fbf2bbd02883fe3a6a95e5f5b4d193573b3c818e0f3b0a440df8d69313a6245df6508ff043192afcafc5cc3057dfc685e361b930e14f318576ca0e58f1f0064eaec1014078ffd73223871959e085978ab92c6d7df1840e8cf9c08ff1e8b32b0174a84160742077c26e4c6980e4a9a3ed9397dea7306aa7cc9a5cc21e97899f299ebffe800c3d93ca1fa248f95bebb003cbaa7cab6e317f4c790ef916a7470b1eec6d5860068ccfa37358ad4d6334c001a7b2c414654e28f8b92f6fe81e385bc4003c05d0152f520c015eab110dfe760b6b93302d7e28d4f2def7791d70800b5e71b9c6c04fd43a6d869c96187d67b1d1226087c7a31f88f0fef118043451888eb219b0303555e0c11d10b7e3b6ff1ea5312f6caf22e5679665d63d10f3e60929f4bd44a04eacb825f5ae19e297b7418b125c59ebafaf418adf802c6cf3c07e38120397f00cd7808095293e06e624d4854a799c9316e94b1694f30ca36fb5071f1036e33022221b7fa99702ccf6ef06503e521148c0141601b05d2de146955372b49d5eb002d71df8a95c9165fd1e99124455506e6e2e91655049ce9cc396c808137b2a6012794a275b41191887446165a8f3d85f1cfe63e123503cb161240a5e9184ede017e4f256339af0de5cbced9ae082e1858a869c3e01f242f4abb7fc626ca39c9048ba0a93d1d83de0805177f64eeca59f97d06911a10de13c3069795e75ae5200677e0e834f5f0243a48da59501fa942387edb2796e9ec1682a90316d109e017020924", - "0xf8aa098504a3a2aa9b830f42409438af6928bf1fd6b3c768752e716c49eb8206e20c80b844095ea7b30000000000000000000000009051dc48d27dab53dbab9e844f8e48c469603938ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2da0ed39530fc56cd555d9edf1b48335964f6deeedc67347b21bbc2a5c98fff74a9ea00665d2ddfe662641426020ddfdd86e1b5724da802cfc2460067f8640ee17aaef", - "0x02f903d2052084318d34dd8506a7e5824f830f424094683913b3a32ada4f8100458a3e1675425bdaa7df80b90364b87b0b4c000000000000000000000000c1c6805b857bef1f412519c4a842522431afed390000000000000000000000000000000000000000000000000000000000000060000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000002c4ad558ab9000000000000000000000000e34cfa1c2dd8aad94083335c9c668891470b4783000000000000000000000000e34cfa1c2dd8aad94083335c9c668891470b478300000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000001215be41b7f978000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004e818c23300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000644ab3940000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c001a0173aedff223dd364bf83f60d06377defbedc8eec888bc27bfc96fcca77cae06ba07db9ad843372885ca8f8cbf13f9b70bcb1d48270755e9cc5c22b7302af87ddc5", - "0xf86d819585049588ea4382520894092ac2bc42681b3ec6f4c79440dd6523b333d33488047425618743507a801ca050ddf80cba14a853de23973684377163521a055bcc2207c46784c6ab25bc6819a050135772b960805aacbc473a893e41be1cbb168311e0106c9362481291e5d143", - "0xf8c91285049588ea43829c669450b96c4374efeea0c183d06679a14e951e33b4dd80b864428dc45100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000f4b2cbc3ba04c478f0dc824f4806ac39982dce732ea0d4b02d3b09b9f5a1e8f5f12e93b6239ae6a16feab2cf9b4d5ff57a7563145153a075dca01d7467d4565105b6d919b295800d52a9e10d5d1fb4b88c6ca48b9143ef", - "0x02f8920581ac85049588ea4385049588ea43830249f094d8246f9c6cc0f006de446ab90a787942ceaead7480a47c279171ed5632bd9328325120a0fda3c3a4a9c50c52415043f5bb37efed86466eed94ddc080a0f031b5a51de8a493317db4a718533a7bd4a58f9a2f69f36d12bb67e46cd03ab9a03aaad83b38ae539f075cb2adee1fba5df9ba5d95eceff2989842a3f479c1f95d", - "0x02f89705538504808a64428504808a64558302861594c3511006c04ef1d78af4c8e0e74ec18a6e64ff9e861b48eb57e000a4b6b55f25077d9197bbc1b0ecdd8a4b13859406fc4beb908b708608c780fccf43a7a52ee0c001a04bdc1d7aa306f2ccec800d96f31320dfc74e2de52fcb4dc71fb2988e5566f45ba0109eae4d06bd8cada7f5785c8f36d93f75df5883d80d335cde986e76e2856bc9", - "0xf8880f8504808a644282f422945a94dc6cc85fda49d8e9a8b85dde8629025c42be80a4a0712d6800000000000000000000000000000000000000000000003635c9adc5dea000002da01f92d12e105343183ad791267f02e00374915ad4232a5a3734e4a153ceca81aaa03c11480d0055fbd8135ac220ae1eef9dc704597f11e45f7aabdbacdc8ca97ba6", - "0xf8b05c8504808a644282d55694fad6367e97217cc51b4cd838cc086831f81d38c287b1a2bc2ec50000b84440c10f190000000000000000000000007e1f1a7afb223208874f93b41449d080d76e0a8c0000000000000000000000000000000000000000000000000000000005f5e1002da0118b30965cc27a1336b68e3ff927af76a80cfb509dfc65ff83631758dfc41b8ba015f882ff83615aa7902f1f150d3833e2fa67f06528ba2230f36355bdda2f86aa", - "0xf8a95d85073109ce3a82eb869407865c6e87b9f70255377e024ace6630c1eaa37f80b844095ea7b3000000000000000000000000889cd829ce211c92b31fdfe1d75299482839ea2b00000000000000000000000000000000000000000000000000000000002dc6c02ea0cb2ee441ef991e62306d88b714f31a947906ab93f91d689876949c1f3e9e9bd0a067b9d5532a437582ec12f3828741584f91fd3d9cfdadbca214c647692aa5dc89", - "0xf90131048504808a6442830186a094e93c8cd0d409341205a592f8c4ac1a5fe5585cfa87470de4df820000b8c4e9e05c42000000000000000000000000a9369e95caa1ec951079acce313520e7b77d5d5f00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000002da09525b047b3ba9895b340151a89ea622c5e72c0b82f7517d914931bd158d08e29a01f33441185d51b0bc2dd67e33bfbce23070b659273f513d5561baaee40b789e1", - "0x02f8b705058459682f008507ddfb85da82d58694b93cba7013f4557cdfb590fd152d24ef4063485f87b1a2bc2ec50000b84440c10f19000000000000000000000000a9369e95caa1ec951079acce313520e7b77d5d5f0000000000000000000000000000000000000000000000056bc75e2d63100000c001a0da0de0df5c0ff8dac76e92af295552b74c1d5a24599497f151cc446f32e230d9a055142faa2197abd59da3b4e453bb8c702edb9e598d44ad47440e8aadd5ab07f5", - "0xf888108504808a644282f422945a94dc6cc85fda49d8e9a8b85dde8629025c42be80a4a0712d6800000000000000000000000000000000000000000000003635c9adc5dea000002da01140423c7aab99ababa4187d25eafb5b83f596a194a6fe1483393255631d6022a020f01ec01574b05cb2a62c5a376bd2d25265452df5de4d6691bbddd4f676ee51", - "0xf889038504808a64428301a41f94aaac6f9d407591909f1602762806e657eb12e21780a4ba83d1a00000000000000000000000007c3fc57a61806a7308f0b1179be0f054e37947f22ea0057f16b89762c679619935349c1c59b2754a20c35375c8b52175816c50051a13a05d244cad676145fd27831c07c2789c4e28677980d6ee0b057a9db9bbe22d1242", - "0xf8b10a8504808a644282d5869438af6928bf1fd6b3c768752e716c49eb8206e20c88016345785d8a0000b84440c10f19000000000000000000000000e540f0591fedd571b0f393f420fc7a89219e801800000000000000000000000000000000000000000000003635c9adc5dea000002ea0ac8ba8b9396bfaa5ad3bc2933afb1711622a7380475d3eb5bc80d95858d48520a070958f0bb7a59210f4c1066908e7c1d0750619e8a872bbdf3c8ebe528c929371", - "0xf8b00b8504d2c0a1b282d55694fad6367e97217cc51b4cd838cc086831f81d38c287b1a2bc2ec50000b84440c10f19000000000000000000000000e540f0591fedd571b0f393f420fc7a89219e80180000000000000000000000000000000000000000000000000000000005f5e1002da0b5c15c31931e4adb252fb43871d3e92f16201d22015189c3519e3132c9b69635a013eb296441cca7b4473efce2e254c3806214d3213763a3a89dc51fa0d6fdc5ce", - "0xf8a94d8504808a644282b76194b93cba7013f4557cdfb590fd152d24ef4063485f80b844095ea7b3000000000000000000000000aa1603822b43e592e33b58d34b4423e1bcd8b4dc0000000000000000000000000000000000000000000000056bc75e2d631000002da0bdbd7114f50df257593dd512d151bf616fd0d8912a4b07ebc0398ef658f4c4e6a003e88fa2a0508ed0ef48145e96ac18378fe456b700484580ee7f6e95de2ba1f6", - "0xf86b358504808a64428252089442cc37539f2be1d208487334045c3067725ac40c8701c6bf52634000802da07cc93bbe005cf3f3f23ba7c96016764abefdd7aea738ce074806236d6bb110a7a030ee12bd4031f6631823dc8658c0b51cbdb74234699ae36ef302c47c7fe27733", - "0x02f901390502840a6afe658505a9663a70830186a094e93c8cd0d409341205a592f8c4ac1a5fe5585cfa88016345785d8a0000b8c4e9e05c420000000000000000000000007e91953591451abdb0a11ec0300ba01014f4ceec000000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000c080a02ba70904b4e844fd84c998eda238599929d68e3af068118bd498a05ed48bd7cda026f71bfe8ed8cf7abc663e92ad1fd942de3766c0970441ae9d1bdd315851ecc7", - "0x02f8710581a78405f5e10085049588ea438252089403312088b906497859c26de7164f7f365776f81c85e8d4a5100080c001a0c7fbd660587ee5eed5f101fd6992079f30514ec5c5701994b4bb674e5b58024ba011964125b1196fadb2f56c0222b65b634f1b01b98ada5d43a026fd258d367272", - "0x02f8b4058309a36d8405f5e10085746a528800830186a09407865c6e87b9f70255377e024ace6630c1eaa37f80b844a9059cbb00000000000000000000000020361bd0066f87a721d9b95cd93503c1210396ad0000000000000000000000000000000000000000000000000000000000989680c001a0be61ff652fdfe8ae3b1b53ff947004eecda1676eea16ffdac9660fee39fc2184a053fcb46ef2f99d264072f8cb6c9a698409a5f949dcdef0bab9b6b2a99acd1554", - "0x02fa015b96058302dced8405f5e1008509251bf38683315820943c584ec7f0f2764cc715ac3180ae9828465e983380ba015b24cb9054990000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000033800000000000000000000000000000000000000000000000000000000000003bc000000000000000000000000000000000000000000000000000000000000045a00000000000000000000000000000000000000000000000000000000000007ac0000000000000000000000000000000000000000000000000000000000000aec0000000000000000000000000000000000000000000000000000000000000d4e0000000000000000000000000000000000000000000000000000000000000da40000000000000000000000000000000000000000000000000000000000000df400000000000000000000000000000000000000000000000000000000000010180000000000000000000000000000000000000000000000000000000000001328000000000000000000000000000000000000000000000000000000000000000e01e545e1c48f91da2516ec5188c581ffa34b44544e5b4d4637149d91099df922d04388d5e00aa25d0d7a3eb6e3514f75624b7d84c0a675e83d36e65748d8a9c33beedb71d6377745a91e41202ff61eba514a1bbecd1576540bcf3e3511230ad140000000000000000000000000000000000000000000000000000000000126cec483c466aa127f8b687f694c90eb3a2bbf7fc6e480718dcb88caef20f9ee2d11e000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000035b7571ca144185e5da901bfc28cde8afa68f984d625a727babccef8e9b098379ff49fc7c0ee2243913298b62d52a6ee35dbf60fba2372c338521c621723ca4af00000000000000000000000000000000000000000000000000000000001c528b0000000000000000000000000000000000000000000000000000000064529c0b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a12000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000eee3412fb24ca52c696e567b60067828b321bd4312b005dba9e24f185d646c5b7571ca144185e5da901bfc28cde8afa68f984d625a727babccef8e9b09837900000000000000000000000000000000000000000000000000000000001c528c0000000000000000000000000000000000000000000000000000000064529c0e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a1200000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000009e377f325dbb87de8cb9b64f1b669de1713ec78fbde2c63be60e484a3116d49400eee3412fb24ca52c696e567b60067828b321bd4312b005dba9e24f185d646c00000000000000000000000000000000000000000000000000000000001c528d0000000000000000000000000000000000000000000000000000000064529c11000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a1200000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002df70000008df88b828698830f424082ce2f94530000000000000000000000000000000000000280a4bede39b500000000000000000000000000000000000000000000000000000004a9b5bcc983104ec5a06fc6d4c6d9a65a1978e3ae115a584bc1079af980afc74d7fb82237bb227cb3aaa01aad9d6a6c7ad6fed4eceaa019e061fbdc9a0457ff3f33d7969f00213460cdea000001f2f901ef830735fd830f42408302f9b894b75d7e84517e1504c151b270255b087fd746d34c80b901848ef1332e000000000000000000000000429b73a21cf3bf1f3e696a21a95408161daf311f00000000000000000000000032139b5c8838e94ffcd83e60dff95daa7f0ba14c0000000000000000000000000000000000000000000000000576f62f31bf18000000000000000000000000000000000000000000000000000000000000240d7700000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000a4232e8748000000000000000000000000b56d9eb0de21bc9ff6e9673e233bef831b932892000000000000000000000000b56d9eb0de21bc9ff6e9673e233bef831b9328920000000000000000000000000000000000000000000000000576f62f31bf180000000000000000000000000000000000000000000000000000000000", - "0x02f950a5058301fa8e8405f5e1008509414f7436830550b094845310000000000000000000000000000000000080b950340040bb7b5d03d37d147122e7233d72f27f00000000501c78dadc7d075813cdf6f76e123a281de9a10802d2bb8a80f426a125402cd9d0417a132ca4812896808808a26b5714454525164014512c288a8a22cd5eb000221190ef49508cbe2270fd737defc7e313939d9933677ef39b73cecccece32b82f034cee8b30699b5d7d708feceac6aed504bf81f607ed617b13eab482fa50fa09a846dc2b636aa6df4d589d37ddf76ccb54fdd8b7451283d3ba055e3ef65ee675fdd9932dd88fc2f942ccb5b440cfad0b98dc490cc45204139140059d0d11b408a70680f5319b2a387f59ae72f9d973afcf74a8d82c5c5d08023b6277709ff1253110a85e8919b3803ffb6b1b239d6b8cf4d9bf4f06d19cbff0760f76072e4ed92d4d96af0a4adb712c6c41f8a931ca93c6d24fdfc0dc54ef3f6fbf1e14374b5757db0663ed1b931a11ece79f608a314a7471f424da18047b85ba415e36513863c364bd04e79848d7189be409cab7c6d70d9c57964263e442fced4bf7d41fd5e44a9ecd3df3e6974f6a072a537c6e5ec368a6ea57b67e99a11cabdcf47ce0ae5cf6a1cf7aeba59bef4c8db8ba65d7a345abe5c6a8a08a045fdccbb3bc46ecc87584e1175b4a77c6d3cf45e7b3a85abd458e16b4324245d46d5859d3fac37cc9ad35c74b882b85e768976ef3f3c796be480684cbdef2e8ec0ce960808b104cd09f453d2b9a5fa82ec0fa2052c1ce4fb91a3413b15a2579d07d6163ecda6eadebfa4ee25757a12eec78b2fb2650fe24ad3bfcc41f12f0870e2e564e149ea91022bab52e00bb8af09a786b48d0e97785033d77a0c6908fe0fc31ef9fe9dc9c3fead7af8c50ebe169792631e07634ab4fe379f15abe2a12fc1a21540a774a1ff22dabbb51f279775e37adc536fc446b6f8896461e7583ee5e586c4365a784f68ceefdbb28f639530e57bc9b59b937ef62ccebc81b42ed5260b82a035c8860827e2c801d38004628cdca15776fda690c2e34ea3df0187da9f9d6c25d09a8b20c44f4405ce924e03bf3ac6d4de97ddd5e7542de4c207d879a6bbccccdff4b7c9d96bb5a5943b3ef04aa13ba9fcc5b7336f3f89e20cef4bbce1e769b252e681daf713eda026d5b72deb77fa80a8493627149c64d25461b12b2e30773a3d61a2d7758b376775e929725f929def353169cf6dea847f5e0f99855279b7d53d4ee09c574ed7c2b5ef049a9f13dd1ba9faa5fc2004d114cd09085aff308beb3a853e759e596a756f1f52aee14ff90d7613028beb7eff03cdd1da4f28bfad73d4b47376a7a96bbedc8d563b49cf05be4f077ab2682dc0f7fcad38ec9ecbb613c6abab45a06d7315a471508eb7b251ac515b7f3983177f715bcb11ff41d70bcb74e5c3cfd9c118d11159067022bf68a6a1f5d62bd8bd2969d1080d8bad6bba3f1c9f5faa78b9df81cde77631ead6680c700267818ae6de50a7c9689b5c3afc70baf92dfef4c71f55ee55244c916ebbcee519796d53c6e57b688091238e83ef707badbff9aee20f3fd939d934077de9a33c27bcf896f5fbb558f764961e9ceca8ff70bff05747f7c4df4ccb12d87dd2e0f3e7aacda7731ae33e919fe74d04c47859a33e4002fdfa9b0522742e8d9c737921b69b7fca75cac98e2bb70d514118f947d2f33346e9fd8a7d259ee0ef4b9c29b423f2e2297c99846cd8857fb70fddebd50a9471b10fdcbf74618886bec96de693bee2e23543110d70126e20afcb6cd66c6acb327a96a4d2be6de102af0dcbc406aa9a7feeaf971170222c562979fa666fadd82e30eaa331644cd29dea8de1557e3dbc6dc81eddb2fff992a7142eb556e4bf8c3b32c9144266219474023c83128790d5bfe664083fab38067d2031a5462587c0af0a7018d116493906a0339d8e2f412ece6b9274445277bc6479944999b99a71adbebfb87c53819ba6002b5172f0d996840b3a8ff70c7724be2d10f0f1e32af298a9394f515237c0c2acedd15b0452d79aa7b32f5cab63349d0b3a428dda569ca3a947ccd5ac33bfa68d4d94b9b4c9d2ef9d788c88e1dd0f8ebdbae7fd779bd53eec5a79d952f4e998754a0df3cd14a9962d2aadf49a13a98c173ed661d906bcaf0db6c74bb4c95ac7b2138c552e7ed867d3d5b939ebd69821c9418026a00534019de95b5c9c9c043bda5c52824a5cd2dc579c9d5938b3ebb3ecbeabde3b9b97c262563dc7c0e64f2dfe1889250237cb6a422f6b8e63a3ed341de09b5c8de9812c7f7c6727ff1ec2b029756f1ef5ff6d68b349659e34abc987791ffe044ccdaa2c306332e91c32a2b03ef36cfeffb58ccff6e65d3efcd5ad1d2ffcb28e9de5665e1c757a65779b7ec28505e4336f73ebaf15515095eaaa2107d6bf9c73b1d79999e850b0bf17a5db3d2d713325a663ae01899e4978ab0fbcbfb897b2f18e4351a2f71c0cc37e4df400f9fb155edb9956386f9ab8ca9f6cb39dcc69cf184a13cd770368e7a93e03736f5783adaa8882a867c2a5e75775781bae3b5997bc6f01b7c931e868230ece657d0b2bc729595f0fd15b7d28d86ae9e95ed4d3d345d09a3993aeb8351a1c7f6abfd1d649a82a77cc6f4b75b654f531399250bd6486f399bdf6a44b3c789b98eea96f34671cb672d0e644e02bcb31a2f84dfa6e0ceee3c6360be06a1a3c22d1beffc7f09ef586e59ad2efbadf08d575a5e7559475285d63335fa8da757817089f1ad454b6f079989864f7ff662fab54bf7faad2df396465fddbb0d279fbe3a78166c9a6fc9fbeaf53ac5cf030a4b249062fb766aaba73d672e7febb3fba6e2e50da2eae58d88be0616ba86dfd1a5", - "0x02f913f6058302fd658405f5e1008509414f74368303858694654e6df111f98374d9e5d908d7a5392c308aa18d80b91385d0f8934400006265c600002a00000f000000000000000000000000000000000000020000000064529c6f00008859ca0000020000000064529c6f00008859cb0000050000000064529c7500008859cb0000000000010064529c7a00008859cb0000010000000064529c7a00008859cc0000060000000064529c8100008859cc0000020000000064529c8600008859cc0000040000000064529c8b00008859cd0000010000020064529c9100008859cd0000010000000064529c9100008859cd0000050000000064529c9800008859ce0000060000000064529c9f00008859ce0000020000000064529c9f00008859cf0000020000000064529ca400008859cf789cb45a755894dbf6fe865204060409c10308488788a4289d2aa584228d80201d2a20354849c80175483fa45b524a01490191904690ee430c9dbf67e0dedf85fb3033c7a377fff77deb597bd67ef7daeff7aebd060042d68318215e89dce15ece6c8a119aa2cd9b9141d6d2010917dd899edff58318c93cd60900808491c8547de0d0c0177cd16d3fe922d33cd5609343af5187eb43fbc58b851f4c34cc3f47e5a0fed6d940e734a19acbea6991570b52f2e9599bfc1d82b384581aa075515ba940a3e23c1ee3c3812f4f77a14a55b35707dbebee65059408f2c9a8650140ca7a1239c42bdf343c5ec75da73b92cf5cd2add4a89ab50aeff9435e5c8f22697cdde4bcc3a1f0486b4a7944dd675091716b122cccb8b14ad0761d387e6037daaed0d5680180178b00d8467292b08396df228c50386565a7f052fe645efd578e80dc3f82472b3303bfd380a26d6724ca33d264ab70b366625e48eae9b08159835b91b0bf983acea5c9b6af00904b1b101e02080c5b8126fcb828fc02ea1871fc2701a0a81a81db75f67024c7ad0d45d0001bf875b35a37d614a5ddc257f2c985763d54f600720f796dc6a3efa2b28d24f13d9d189cb8bf7d5ca0c767b7dda1a943e58f1cc66af136c8fd45ac0b5a9269d6cf62d3dd596871232419d3062b54fe28a9ad5f61ad8db037100519e99e1197babd37103e991ca9447fce2187f9aa9e84fb9b6a3ab17a6e998afc1800726b03a2720a02c32a9f3c16347f5c8b3a5d2e231200281a75479817a0080812bde8b8d828a028822e6a00003c0e3f28ac9b86ef6a584e77af9ff5651bdb41b8be5f4dc7b06a230cf3631d7ea8485e7cf7191e52462a6616a046e69b48feaa57eeb0fdb85d47a6a263cdcd0f32cf77dd63f965b72c4baf2e5b1591ce123517b97f66a679e22de0b8028aa7fda99ddcd0ca3dbf20f68052f1e66aeada1c9e1e07655de617d3b6fe77f4270f529108998a7ac7a722d18fc2bc64e3e3529154a0ffcc7c3ebd672b3eb69b3e36e1edde0b394b28970b110ed4d8d6788cda2eb8b9e755198cca4cd48c10b1861dd913c08da958eeafbb12d46e915ceeca03aa78b5a43417d1216eac166f864c452bcf04b6cdd09481c56b5b08375979f6feb7641b448b2667aaba9c685b8c7370402ed207ed1ae236d58903292eb0aebdab3ab42403814db26eb8a48d9bf28b8f380188c506c48c1202c3aa143b16348f62088ed01ca530ba68a8a44e5d4061c2b9a5c57ac6a756ca029d3f0000e0e1072deeb071d3ba9698a067dbd3a160010109829b1e3d1a714c18e63f92a2c711f7613baa14bd6b34be71d5ba30ec0a73acb1a160727f9275e30df298551d5afa42ff9ba3dfe441da1751b3cd9ffe94cf75c61d71a74578445ce19a89db5b78742aa8a9baac2f2a1e0082d703797ee3a746f8e697e1913b5b2b7e2d138a88b329a3af08637f288f04135a08f3337d4bfe48fbe6e3e060eb1069baf60599823fb7b2f15814469d3849dd2e5dd0be7a7dca80480f80a86d4094914c14a47bfc9959bbe2bb812f72113d11010079c49e249b9a2d865d3892f4c566e129b445b0d51b044b9b73b8aa2d9ffd487bd0391bab453b6298ffa788e8b8338fc4b4b82d163ab8d8103788efe310d21d73bb59fd01355cb937ba74c05c3930993813bce294b0e503a342843665db252c2ce704425d9db66e0266ceed1ca7c8146b7a0fce14360486f5703b5c667cf57ccd9c0f45d35654c94cc686514029c0873c53548dd96368d7027fe5816a95bb527fa654a839e16340e3c899b2f5b1f6fbd60313bd5b605d3e9ea550b0602d82f64c1aabc5516198ff08daa9ef399b22ccb267e1a986c20569f2ddac93dd2c87edbe974f4375fff82a15ed7e3be6bdf898ec6e0a970912ed3984054dfa582bc5da0d22b13e7b75515d371cf7bdfa1030f9464ca957b0ac0d28c728544127a2f1e2f507eb60bc4e7dbedb8c3119e5da5cccf88d9e125d1101ca0768b3fe7306bb70d19ceaf9cda53494eb843e79d93872112d1fff37dab0c2d3296a95148556ad2fafd867bbe7fa18de3541e76cac16c78961fe236863924ea872fbbb64cac38a93fc8667e03cf9eac46b64b8c3ce3575fccaf6526575cd5d5ff0f34183cb2ab205ad6c5aef97c666941249ba3212619449425a6661dc76591146d603fb6219e7b7319800f8cc72c4d7083bcc71567e77b45ce3ca1b32d304e3d9e74e36a6866ce32ea58b5de0ed64feaa3ec9491aae7186aa02cec621ad604e91e26cbd793d19b1977015a6cbfb11d1fe464ef57d51cd1ba04cafff483dafdf429cbb700c41e1a0a090596537b37abec0f22f05f0b4e0e28f2fb6db2f6fdb62cd8c42a8796e373eb3d3b4f24bc0c673859ea67bc9b22fdf4f42bcf249c38fe3a05f93ef580523d914397e48f9ce0f5efeae5850643e53aef8560f913a602220", - "0x02f8b4058309a36e8405f5e10085746a528800830186a09407865c6e87b9f70255377e024ace6630c1eaa37f80b844a9059cbb00000000000000000000000069dae868ffde59560637e21af369a7bf1f84f03e0000000000000000000000000000000000000000000000000000000000989680c001a08816035c5176a9f1e564993be46c80b90b5925c3bb9bad3c5098f44df22a1600a051607e78fe767401331c400f0a28a8079da665d92ad32c54b2c07ef84f053772", - "0x02f90b7505827aa88405f5e1008509414f74368301008494ff0000000000000000000000000000000004206980b90b0500669689d17d3e71a334ef9a09a2909a6b000000000aed78da8cd6e93bd4efdfc771e52bc6d2488630cabe4523fb9665b2650943592b09636bac21664a339821a6420c85b1244b5296b2262963694463897eb44ad992253bd7e1b8ceee7ffe81c79df33cdecf57bd1ddbaa0d1d337158cb462e758e40dbde4bdeea1f78566ba8dc74255a2955747b105b314724515cdfd19d094f573602fc5a42224478956e1097e9eb9a1538db92d08e4ba247d4b58f38c77b63eeabbefc7ff07ef7785199b4f662ae65e63ed89c68bc8ec1a318a54b9d96bd998df050a2ba1b64500d80c6d4f4fe9507cd628259e284489581194f9844abcd9bd49c0bc31ff6d08a544621831a00b43d773572cc8323463f577f1cd6bd6848266ab02f4b3dce23ac0a0514c5b6be830c6a01b04fa77056c0593f2b386daac205778f7cffcbac59f5abeb4944cff4c3be2a63c290411d00067cea76bb479ed7dcdac7cb14ac7a33ced2d67414b068bb1c81f15039f6ed331932a80740c521a7131ed3e90cf74ea5eac95c557d9c82e4b6c8cf9699960599f342d50939904103009ee853217e58ddd8aa915b231fdf5a12b4e838eb707e9bd0d0b14f6ab5e36b10f46f6308c0e204ecc76307683ef881758ed683af9c8e965f814d9c92db2a9be6cb53839da142068d014852ff8b12114acf9e1c7a1e322f65863792a819b1c47bb2b19a34e1f3391ded904134006d7ac6fdc2eae7e9d6489ff4d06a33456cc5f4d69db207981331bf9a9d7750872183a600dc23c51c1937b87d63f49e42544ef9ed8534c5ada2abb633bd962491f3c1a5024f4814d73eba3c57824bf338fc78e85c2e62ebd022cfaf6f4eb18ecc1fdfb3cf2ef3d3f8d65276417300567360362bebbc868b8e75c28f38ea4c1eba9be49b9b22bcc6e20bd53bc0fbb61c32680940112d9cd66151fbc29a27be74b542c6fe700446833994efbadfbe676f09f9742a64d00a80771e7af1344de09bb878427c3f20cea29d7d8abf5d1bead5edf5d52f402f53ba218336001caea0abb227af3bfa5878afe154e5d149f971bf13bfc2d34e062d9e31483031870c9efef7cafd0873f70faffbbc0889e7d86f9035e5d8ee205e9365ea522a89558edfff6b23515cfbe96115f20d1e3883f274f985b0372e9fd70aceae968aaf93107547a732c6033e36ef82f600b43b89fba36d0c33acef28a8cfff121c33802b4b3c5c7c15c6d9595151fb78a21932880120dfa799d85c4b0ac725599786d0f8a59f62771f66bfe8c16014f285904a28f21dc8a01300234362887df9ed4126d14957d9e3780f6c9ee1e6cb94bc3d70d9a9edf663278312c8e05900feb078541ac2a66a9df1ab384471b17b3ee8296376bc6c54336867627009ed6508197401e0c9acee1d1c13ad8c4ad3b744bb2e934e4c15dcb39dc940dd1e9f52793da42f0519740320b2db4aee2183df1fcd2d4b103c48bcf4373f2aa9ee8d10a7b8d0a9d033b1775221831e004c646ca7aff5c97973d85e3633a8e86632d3aadc507fbc2cdf1afd9096d7b88827515cdfd3fdaa5a62bba585fc9085fe394e2a8123a929c96c3118cb1acd788d820dfc65a15df03c00895fe3b45a4a0d099275b4c9cda8d30896ed279128839ebb0a02bf9c2f48b68840063d01e83f575a5945591aa69bff3eaacd5f882a1eb5d8d1ae74d18dbe92eeda202c49820c7a0170da8cc6ebdb2ed92163c0c625c4a910a6efddf7d0f0f8b2c3c59854d1a51be81b9041ef7fe72b0f556383fbc8dfca9d6f88d709a96916fe9f1ad9c36a234b6f9f459bb2691d64d017804fb2a4604ba5264359e10eafba9496785911c9ee0a93f0c7eb89e94130f2116312c595459f98c27e7c5cab76a8642b6820d4a8fdf8752e42c85931d55ac251cf2b276462dd76413f00cae0c2067c2a901801ab645a9e9783dead70e50225875bb267d66b8fb36d77f242060300b8126eccbe9cc1f7be94c13526b371a1b459f063d1e9aec938962efe49b5b6d917c8601000ddf86c07b142cf3aaea0ae8f45b5067b07bef87d7f79e19ad98fcc328395bc531590411c002bd1869d5ab13cbae8404e3f49b440f55b22f5f3ac8f9dbaf681a5ec1781fc54c86008005392ee4a0eecdd19e5336f38c29fd519fd1ae336a55f60f7f29c754f77c02bfe7ec860180017eb952765f350e391ca5c268832849ed61c5ed6572a4ac254617ea6c71bb13be706e84301d42a2ead29c7d189545a593efc54d213731a1bb3ebd529c680db87adc5a05d300280e5f6e6e29b225fb6c5ed2279666ccfc1ba6ec96c3c95a735d243045d582ac2ba90c14800c65c55f2d1fdb8c78af4ae0ebe8cdcdb0e5f1a4b7d01fb63f8c93edafe27e1451164301a80d8a949331fa100ca4791a334da7b19464ea3a8a21537b7da4139339bc1d752ff4106630098d594cfce1aaa62e9285e239814c72a1561fba946c49843e436593e1683471d328807e0ec8fcfc86783ef46c29985f61a15e94dd30b4d16c739521de2fbbd240a1a04932183d700c83dcdb59ae7ee27e322383fc53b2ae97b300e35f6534a7cd5ca256a4396e0b33b8907e9b0265ffca7ce319f75d4bb9b0cb4cc505798a3a1b6235e823a46b4d226fcaadc05e300e8cb079b67afeffa2ee0fb2633d239a3ae1ad6a1877c10f77753254473fa095210324804a0bbc43413a5f588e6fe7d5fe316c6198739e49076683bc24851e525dae904d11c32180fc07da65441aa79e6b1e8fcb1ceba42c69480ffc928ce30b29058c230ae51dd3105329808c097382e23aa70f250f570f51e9e9d36f902cfec96a53af199", - "0x02f8f40583013a798405f5e1008509414f7436830156c294e6dfba0953616bacab0c9a8ecb3a9bba77fc15c080b8849aaab648a3c315858d02541ef1aa93feda9c3a1245a05dcf8db82f60edf29b666edb1390000000000000000000000000000000000000000000000000000000000087187ccc400fb13ebf36bb86163429ac697486a69f6f5fabc79aa9e36b3c7a6cd030f100000000000000000000000000000000000000000000000000000000008859d7c080a05d427735b37c30edc668e5346a1cb593eb33fdee3a11221481bf29dc7666958aa00a03dbb34ede5e69e754efaf86bc19dc0d0a6235d04d8aad78847df1679bfe2a", - "0x02f9567105138459682f00850473c901ce834bbfbc8080b956176080604052601b80546001600160a01b03199081167316fbb520f1774dd702883867c5ef6cde625fb64b17909155601c805490911673d06d855652a73e61bfe26a3427dfe51f3b827fe31790553480156200005957600080fd5b50604080518082018252601881527f41727469666163747320627920456d6d61204d696c6c65720000000000000000602080830191909152825180840190935260048352634152544960e01b90830152601b549091906001600160a01b03166103e8816611c37937e080008083733cc6cdda760b79bafa08df41ecfa224f810dceb6600189896002620000ed838262000986565b506003620000fc828262000986565b506000805550506daaeb6d7670e522a718067333cd4e3b15620002485780156200019657604051633e9f1edf60e11b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe906044015b600060405180830381600087803b1580156200017757600080fd5b505af11580156200018c573d6000803e3d6000fd5b5050505062000248565b6001600160a01b03821615620001e75760405163a0af290360e01b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e9063a0af2903906044016200015c565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e48690602401600060405180830381600087803b1580156200022e57600080fd5b505af115801562000243573d6000803e3d6000fd5b505050505b506200025690503362000366565b6200026b866001600160801b038716620003b8565b620002768462000464565b620002826001620004ae565b601892909255601955601a80546001600160801b0319166001600160801b0390921691909117905550620002ce9350600080516020620055f78339815191529250339150620004f59050565b620002e9600080516020620055d783398151915233620004f5565b620002f6600033620004f5565b601c5462000310906000906001600160a01b03166200051c565b601c546200033890600080516020620055d7833981519152906001600160a01b03166200051c565b601c546200036090600080516020620055f7833981519152906001600160a01b03166200051c565b62000b9c565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7690600090a35050565b612710811115620004025760405162461bcd60e51b815260206004820152600f60248201526e45786365656473206d61782062707360881b60448201526064015b60405180910390fd5b600d80546001600160a01b0384166001600160b01b03199091168117600160a01b61ffff851602179091556040518281527f90d7ec04bcb8978719414f82e52e4cb651db41d0e6f8cea6118c2191e6183adb9060200160405180910390a25050565b601180546001600160a01b0319166001600160a01b0383169081179091556040517f299d17e95023f496e0ffc4909cff1a61f74bb5eb18de6f900f4155bfa1b3b33390600090a250565b6013805460ff19168215159081179091556040519081527f38475885990d8dfe9ca01f0ef160a1b5514426eab9ddbc953a3353410ba780969060200160405180910390a150565b6200050c8282620005b860201b620022971760201c565b62000518828262000613565b5050565b6000828152600b602052604090205462000537903362000682565b6000828152600a602090815260408083206001600160a01b038516845290915290205460ff1615620005ac5760405162461bcd60e51b815260206004820152601d60248201527f43616e206f6e6c79206772616e7420746f206e6f6e20686f6c646572730000006044820152606401620003f9565b620005188282620004f5565b6000828152600a602090815260408083206001600160a01b0385168085529252808320805460ff1916600117905551339285917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a45050565b6000828152600c602052604081208054916001919062000634838562000a68565b90915550506000928352600c6020908152604080852083865260018101835281862080546001600160a01b039096166001600160a01b03199096168617905593855260029093019052912055565b6000828152600a602090815260408083206001600160a01b038516845290915290205460ff166200051857620006ce816001600160a01b031660146200071f60201b620022f21760201c565b620006e4836020620022f26200071f821b17811c565b604051602001620006f792919062000aa4565b60408051601f198184030181529082905262461bcd60e51b8252620003f99160040162000b1d565b606060006200073083600262000b52565b6200073d90600262000a68565b6001600160401b03811115620007575762000757620008e1565b6040519080825280601f01601f19166020018201604052801562000782576020820181803683370190505b509050600360fc1b81600081518110620007a057620007a062000b6c565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110620007d257620007d262000b6c565b60200101906001600160f8", - "0x02f902f205148459682f008507bfb7649e83011bfe94a6482ee4afcd6681d0e60bc5f1f05edb1b585dca80b90284ac9650d800000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001e474bc7db7000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000642998dbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011c37937e08000000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000037697066733a2f2f516d505758776662754e4378384a4c47524b5645524532466e5139684a5a346d3756766b3673665263635a6a62322f3000000000000000000000000000000000000000000000000000000000000000000000000000c001a04d066618685e4b27eae175e5a7a632f6d59efa979bc01f005fb5591ba587660da029083f2a4d54a76b57b32ea1d1389671bfb1a6d9a8a243a35b6d3b9d8b1252f8", - "0x02f8710583012c1980850470f912ff825208945cc0dde14e7256340cc820415a6022a7d1c93a3587fcdfcc79b1a06780c080a0a7abeba60a2a098fe89f78a9e95ca2958c278c4a2c17cd83ebe053f0afb88e63a059742db5b55927154d73fe8dff5cd2d790b8650f6b68790306a20f0928512753" - ], - "withdrawals": [ - { - "index": "4466251", - "validator_index": "418388", - "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", - "amount": "1927254" - }, - { - "index": "4466252", - "validator_index": "418389", - "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", - "amount": "1936801" - }, - { - "index": "4466253", - "validator_index": "418390", - "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", - "amount": "1882324" - }, - { - "index": "4466254", - "validator_index": "418391", - "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", - "amount": "1934493" - }, - { - "index": "4466255", - "validator_index": "418392", - "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", - "amount": "1944116" - }, - { - "index": "4466256", - "validator_index": "418393", - "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", - "amount": "1940345" - }, - { - "index": "4466257", - "validator_index": "418394", - "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", - "amount": "1918177" - }, - { - "index": "4466258", - "validator_index": "418395", - "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", - "amount": "1913127" - }, - { - "index": "4466259", - "validator_index": "418396", - "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", - "amount": "1862609" - }, - { - "index": "4466260", - "validator_index": "418397", - "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", - "amount": "1922414" - }, - { - "index": "4466261", - "validator_index": "418398", - "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", - "amount": "1940750" - }, - { - "index": "4466262", - "validator_index": "418399", - "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", - "amount": "1919017" - }, - { - "index": "4466263", - "validator_index": "418400", - "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", - "amount": "1901929" - }, - { - "index": "4466264", - "validator_index": "418401", - "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", - "amount": "1871194" - }, - { - "index": "4466265", - "validator_index": "418402", - "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", - "amount": "1855146" - }, - { - "index": "4466266", - "validator_index": "418403", - "address": "0x59b0d71688da01057c08e4c1baa8faa629819c2a", - "amount": "1907921" - } - ] - }, - "signature": "0xa2def54237bfeb1d9269365e853b5469f68b7f4ad51ca7877e406ca94bc8a94bba54c14024b2f9ed37d8690bb9fac52600b7ff52b96b843cd8529e9ecc2497a0ecd5db8372e2049156e0fa9334d5c1b0ef642f192675b586ecbe6fc381178f88" - }, - "proofs": {} -}