Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Sign in
issue
issue
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 23
    • Issues 23
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Activity
  • Graph
  • Create a new issue
  • Commits
  • Issue Boards
Collapse sidebar

新注册的用户请输入邮箱并保存,随后登录邮箱激活账号。后续可直接使用邮箱登录!

  • chainmaker
  • issueissue
  • Issues
  • #1066

Closed
Open
Opened May 06, 2024 by z w@694469927

Rust合约SDK的问题

关于RUST合约SDK有一个问题,在以下代码中仅实例化一个instance

/// get_instance 全局静态实例,每个instance实例一次。用于chan执行智能合约方法时,往智能合约传输数据
pub fn get_instance(capacity: usize) -> Arc<Mutex<VecBox<u8>>> {
    static mut VECBOX: Option<Arc<Mutex<VecBox<u8>>>> = None;
    unsafe {
        // Rust中使用可变静态变量都是unsafe的
        let v = VECBOX
            .get_or_insert_with(|| {
                // 初始化单例对象的代码
                // sim_context::log(&format!("new instance size={}", capacity));
                let instance: VecBox<u8> = VecBox::new(capacity);
                Arc::new(Mutex::new(instance))
            })
            .clone();
        v
    }
}

然后在这个方法中分配内存

#[no_mangle]
pub extern "C" fn allocate(size: usize) -> i32 {
    let vb = VecBox::<u8>::get_instance(size);

    let vb_ref = vb.as_ref();
    let mut vb_obj = vb_ref.lock().unwrap();
    let old_len = vb_obj.len();
    if size != old_len {
        vb_obj.reset_data_size(size);
        // log(&format!("new len {}, old len {}", vb_obj.len(), old_len));
    }
    let data_par = vb_obj.data_ptr();
    data_par as i32
}

然后合约在执行时采用了同一个合约实例

func (m *InstancesManager) getVmPool(contractId *commonPb.Contract, byteCode []byte) (*vmPool, error) {
	var err error
	key := contractId.Name + "_" + contractId.Version
	m.m.RLock()
	pool, ok := m.instanceMap[key]
	m.m.RUnlock()
	if !ok {
		m.m.Lock()
		defer m.m.Unlock()

		pool, ok = m.instanceMap[key]
		if !ok {
			start := utils.CurrentTimeMillisSeconds()
			m.log.Infof("[%s] init vm pool start", key)

			pool, err = newVmPool(contractId, byteCode, m.log)
			if err != nil {
				return nil, err
			}

			pool.grow(defaultMinSize)
			m.instanceMap[key] = pool
			end := utils.CurrentTimeMillisSeconds()
			m.log.Infof("[%s] init vmPool done, currentSize=%d, spend %dms", key, pool.currentSize, end-start)
		}
	}
	return pool, err
}

如果相同合约的两个方法没有冲突,可以并发执行,并且同时申请了不同的内存大小,比如fn1申请了10,fn2申请了5,这块怎么处理的

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
None
Milestone
None
Assign milestone
Time tracking
None
Due date
None
Reference: chainmaker/issue#1066

Copyright © 2021 ChainMaker Org. All Rights Reserved. 长安链 版权所有。