-
Notifications
You must be signed in to change notification settings - Fork 69
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add serialized datastore and clean executeSC.message() method
- Loading branch information
1 parent
2de2485
commit 027ba18
Showing
6 changed files
with
55 additions
and
232 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,207 +1,72 @@ | ||
package onchain | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
"bytes" | ||
"encoding/binary" | ||
|
||
"github.com/massalabs/station/pkg/convert" | ||
) | ||
|
||
/** | ||
------------------------------------------------------------------------------------------------------------------------ | ||
TYPES | ||
------------------------------------------------------------------------------------------------------------------------ | ||
*/ | ||
type DatastoreContract struct { | ||
Data []byte | ||
Args []byte | ||
Coins uint64 | ||
} | ||
|
||
type JSONableSliceMap []byte | ||
|
||
|
||
type DatastoreSCEntry struct { | ||
Entry DatastoreData `json:"entry"` | ||
Bytes DatastoreData `json:"bytes"` | ||
} | ||
|
||
type DatastoreData struct { | ||
Entry JSONableSliceMap `json:"entry"` | ||
Bytes JSONableSliceMap `json:"bytes"` | ||
type datastoreEntry struct { | ||
Key []byte | ||
Value []byte | ||
} | ||
|
||
func (u JSONableSliceMap) MarshalJSON() ([]byte, error) { | ||
var result string | ||
if u == nil { | ||
result = "null" | ||
} else { | ||
result = strings.Join(strings.Fields(fmt.Sprintf("%d", u)), ",") | ||
} | ||
// populateDatastore creates and serializes a datastore for the given contract. | ||
func populateDatastore(contract DatastoreContract) ([]byte, error) { | ||
var datastore []datastoreEntry | ||
numberOfContracts := convert.U64ToBytes(1) | ||
datastore = append(datastore, datastoreEntry{Key: []byte{0}, Value: numberOfContracts}) | ||
|
||
return []byte(result), nil | ||
} | ||
contractKey := []byte{1} | ||
datastore = append(datastore, datastoreEntry{Key: contractKey, Value: contract.Data}) | ||
|
||
/** | ||
------------------------------------------------------------------------------------------------------------------------ | ||
UTILITY FUNCTIONS | ||
------------------------------------------------------------------------------------------------------------------------ | ||
*/ | ||
argsKey := []byte{2} | ||
datastore = append(datastore, datastoreEntry{Key: argsKey, Value: contract.Args}) | ||
|
||
/** | ||
* Used to create a new datastore entry object. | ||
*/ | ||
func NewDeployScDatastoreData(entry []byte, bytes []byte) DatastoreData { | ||
return DatastoreData{ | ||
Entry: entry, | ||
Bytes: bytes, | ||
} | ||
} | ||
coinsKey := []byte{3} | ||
datastore = append(datastore, datastoreEntry{Key: coinsKey, Value: convert.U64ToBytes(contract.Coins)}) | ||
|
||
/** | ||
use to create a map of each datastore entry | ||
*/ | ||
func NewDeployScDatastoreEntry(entry DatastoreData, bytes DatastoreData) DatastoreSCEntry { | ||
return DatastoreSCEntry{ | ||
Entry: entry, | ||
Bytes: bytes, | ||
// Serialize the datastore | ||
serializedDatastore, err := SerializeDatastore(datastore) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
/** | ||
------------------------------------------------------------------------------------------------------------------------ | ||
KEY GENERATION FUNCTIONS | ||
------------------------------------------------------------------------------------------------------------------------ | ||
*/ | ||
|
||
/** | ||
* Generates a key for coin data in the datastore. | ||
* | ||
* @param offset - The offset to use when generating the key. | ||
* @returns A Uint8Array representing the key. | ||
*/ | ||
func coinsKey(offset int) []byte { | ||
return convert.U64ToBytes(offset+1) | ||
} | ||
|
||
/** | ||
* Generates a key for args data in the datastore. | ||
* | ||
* @param offset - The offset to use when generating the key. | ||
* @returns A Uint8Array representing the key. | ||
*/ | ||
func argsKey(offset int) []byte { | ||
return convert.U64ToBytes(offset+1) | ||
return serializedDatastore, nil | ||
} | ||
|
||
/** | ||
* Generates a key for contract data in the datastore. | ||
* | ||
* @param offset - The offset to use when generating the key. | ||
* @returns A Uint8Array representing the key. | ||
*/ | ||
func contractKey(offset int) []byte { | ||
return convert.U64ToBytes(offset+1) | ||
} | ||
|
||
|
||
/** | ||
------------------------------------------------------------------------------------------------------------------------ | ||
POPULATE DATASTORE FUNCTION | ||
------------------------------------------------------------------------------------------------------------------------ | ||
--- Datastore Format --- | ||
[[key],[value]] | ||
// SerializeDatastore serializes the datastore into a []byte array. | ||
func SerializeDatastore(datastore []datastoreEntry) ([]byte, error) { | ||
var buffer bytes.Buffer | ||
|
||
=== | ||
[ | ||
[ | ||
[KEY_BYTE_ARRAY_LENGTH], [KEY_BYTE_ARRAY_DATA]] | ||
], | ||
[ | ||
[VALUE_BYTE_ARRAY_LENGTH], [VALUE_BYTE_ARRAY_DATA] | ||
] | ||
] | ||
*/ | ||
|
||
/** | ||
* Populates the datastore with the contracts. | ||
* | ||
* @remarks | ||
* This function is to be used in conjunction with the deployer smart contract. | ||
* The deployer smart contract expects to have an execution datastore in a specific state. | ||
* This function populates the datastore according to that expectation. | ||
* | ||
* @param contracts - The contracts to populate the datastore with. | ||
* | ||
* @returns The populated datastore. | ||
*/ | ||
func populateDatastore(contract DatastoreContract) ([]DatastoreSCEntry, error) { | ||
//TODO bug -> four empty datastore entries | ||
|
||
// IMPORTANT we assume ATM that there is only one contract to deploy | ||
|
||
// number of entries in the datastore: number of contracts, and the contract data, args, and coins | ||
datastore := []DatastoreSCEntry{} | ||
buf := make([]byte, binary.MaxVarintLen64) | ||
// Encode the number of key-value pairs | ||
datastoreSize := uint64(len(datastore)) | ||
uDatastoreSize := binary.PutUvarint(buf, datastoreSize) | ||
|
||
// contractsNumberKey := []byte{0} | ||
contractlength := convert.U64ToBytes(1) // assuming there is one contract to deploy | ||
|
||
//number of contracts to deploy | ||
numberOfContracts := NewDeployScDatastoreEntry( | ||
NewDeployScDatastoreData( | ||
convert.U64ToBytes(len(convert.U64ToBytes(1))), // length of the key | ||
convert.U64ToBytes(1)), // value in bytes | ||
NewDeployScDatastoreData( | ||
convert.U64ToBytes(len(contractlength)), | ||
convert.U64ToBytes(1), | ||
)) | ||
|
||
_dataStore := append(datastore, numberOfContracts) | ||
|
||
//byteCode of the smartContract to be appended to the deployer | ||
contractData := NewDeployScDatastoreEntry( | ||
NewDeployScDatastoreData( | ||
convert.U64ToBytes(len(contractKey(0))), | ||
contractKey(0), | ||
), | ||
NewDeployScDatastoreData( | ||
convert.U64ToBytes(len(contract.Data)), | ||
contract.Data, | ||
), | ||
) | ||
|
||
_dataStore = append(_dataStore, contractData) | ||
|
||
|
||
contractArgs := NewDeployScDatastoreEntry( | ||
NewDeployScDatastoreData( | ||
convert.U64ToBytes(len(argsKey(0))), | ||
argsKey(0), | ||
), | ||
NewDeployScDatastoreData( | ||
convert.U64ToBytes(len(contract.Args)), | ||
contract.Args, | ||
), | ||
) | ||
|
||
_dataStore = append(_dataStore, contractArgs) | ||
|
||
contractCoins := NewDeployScDatastoreEntry( | ||
NewDeployScDatastoreData( | ||
convert.U64ToBytes(len(coinsKey(0))), | ||
coinsKey(0), | ||
), | ||
NewDeployScDatastoreData( | ||
convert.U64ToBytes(len(convert.U64ToBytes(int(contract.Coins)))), | ||
convert.U64ToBytes(int(contract.Coins)), | ||
), | ||
) | ||
|
||
_dataStore = append(_dataStore, contractCoins) | ||
buffer.Write(buf[:uDatastoreSize]) | ||
|
||
// Encode each key-value pair | ||
for _, entry := range datastore { | ||
// Encode key | ||
keyLength := uint64(len(entry.Key)) | ||
uKeyLength := binary.PutUvarint(buf, keyLength) | ||
buffer.Write(buf[:uKeyLength]) | ||
buffer.Write(entry.Key) | ||
|
||
// Encode value | ||
valueLength := uint64(len(entry.Value)) | ||
uValueLength := binary.PutUvarint(buf, valueLength) | ||
buffer.Write(buf[:uValueLength]) | ||
buffer.Write(entry.Value) | ||
} | ||
|
||
return _dataStore, nil | ||
return buffer.Bytes(), nil | ||
} | ||
|
Oops, something went wrong.